A bit late, but I thought this might still be useful:
Based on the code (and comments) of A.Pissicat, Surfen and Ben McMillan, I've updated GridViewColumnVisibilityManager
as follows:
/// <summary>
/// Used to hide the attached <see cref="GridViewColumn"/> and prevent the user
/// from being able to access the column's resize "gripper" by
/// temporarily setting both the column's width and style to
/// a value of 0 and null (respectively) when IsVisible
/// is set to false. The prior values will be restored
/// once IsVisible is set to true.
/// </summary>
public static class GridViewColumnVisibilityManager
{
public static readonly DependencyProperty IsVisibleProperty =
DependencyProperty.RegisterAttached(
"IsVisible",
typeof(bool),
typeof(GridViewColumnVisibilityManager),
new UIPropertyMetadata(true, OnIsVisibleChanged));
private static readonly ConditionalWeakTable<GridViewColumn, ColumnValues> OriginalColumnValues = new ConditionalWeakTable<GridViewColumn, ColumnValues>();
public static bool GetIsVisible(DependencyObject obj) => (bool)obj.GetValue(IsVisibleProperty);
public static void SetIsVisible(DependencyObject obj, bool value) => obj.SetValue(IsVisibleProperty, value);
private static void OnIsVisibleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is GridViewColumn gridViewColumn))
{
return;
}
if (!GetIsVisible(gridViewColumn))
{
// Use GetOrCreateValue to ensure
// we have a place to cache our values.
// Any previous values will be overwritten.
var columnValues = OriginalColumnValues.GetOrCreateValue(gridViewColumn);
columnValues.Width = gridViewColumn.Width;
columnValues.Style = gridViewColumn.HeaderContainerStyle;
// Hide the column by
// setting the Width to 0.
gridViewColumn.Width = 0;
// By setting HeaderContainerStyle to null,
// this should remove the resize "gripper" so
// the user won't be able to resize the column
// and make it visible again.
gridViewColumn.HeaderContainerStyle = null;
}
else if (gridViewColumn.Width == 0
&& OriginalColumnValues.TryGetValue(gridViewColumn, out var columnValues))
{
// Revert back to the previously cached values.
gridViewColumn.HeaderContainerStyle = columnValues.Style;
gridViewColumn.Width = columnValues.Width;
}
}
private class ColumnValues
{
public Style Style { get; set; }
public double Width { get; set; }
}
}
If you wish to use a particular HeaderContainerStyle
Style
instead of null
when hiding the column, then replace:
gridViewColumn.HeaderContainerStyle = columnValues.Style;
with
gridViewColumn.HeaderContainerStyle = Application.Current.TryFindResource(@"disabledColumn") as Style;
and change @"disabledColumn"
to whatever name you want to use.