Binding DataGridColumn visibility attribute

The other weekend I decided to update an application with a DataGrid and turn off some columns when they weren’t needed.

It seemed to me that to bind a property to the DataColumn visibility attribute would be the most appropriate solution so I merrily tried out the following in XAML.

<DataGridColumn Binding="{Binding Name}" Visibility="{Binding NameVisibility}" />

This doesn’t work. Perhaps not entirely surprising. We expect to find Name in each Item in the ItemsSource property for the DataGrid, but the column visibility should be bound something in the DataGrid DataContext property.

There are a couple of things needed which will make this work. First we need to register the DataGridColumn type with the DataContextProperty.  I added these to App.xaml.cs in the start up event handler.

FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));

FrameworkElement.DataContextProperty.OverrideMetadata(typeof(DataGrid),
    new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits,
        new PropertyChangedCallback(OnDataContextChanged)));

Also add the PropertyChangedCallback handler in App.xaml.cs.

private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    DataGrid d = sender as DataGrid;
    if (d != null)
    {
        foreach (DataGridColumn c in d.Columns)
        {
            c.SetValue(FrameworkElement.DataContextProperty, e.NewValue);
        }
    }
}

Then modify the DateGridColumn binding.

<DataGridColumn Binding="{Binding Name}" 
    Visibility="{Binding Path=(FrameworkElement.DataContext).NameVisibility},
        RelativeSource={x:Static RelativeSource.Self}" />

I found most of this in another blog that I’ve lost the link to, but the full detail wasn’t in the blog itself but was in the example code with it. If someone has seen something like this elsewhere let me know, I’d like to trackback to it.

Tags:

Leave a Reply

 
Trojan Archer