WPF DataGrid - Hiding a column using CheckBox

I am trying to control the visibility of a column using a checkbox (this is in WPF 4.0).

Here is a snippet of my XAML:

<Window.Resources> <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> </Window.Resources> <CheckBox x:Name="GeneralDetailsVisible" Content="General Details" Margin="5"/> <DataGridTextColumn Header="Crew" Binding="{Binding Path=Crew}" Visibility="{Binding ElementName=GeneralDetailsVisible, Converter={StaticResource BoolToVisConverter}, Path=IsChecked}"> </DataGridTextColumn> 

Now I know that the BooleanToVisibilityConverter converter works when I bind it to a text block, and I see the values ​​that I expect. If I manually enter the values ​​in the column visibility property, it will work. But not when I associate this. What am I doing wrong?

Answer:

The quartermaster pointed me to the answer. The page he pointed to is a bit misleading, because the code provided in the message does not work, and you should look at the code example.

Here is my last working code for anyone facing this problem:

to turn our viewModels bool property into the correct visibility value for our column attribute.

 <Window.Resources> <BooleanToVisibilityConverter x:Key="BoolToVisConverter" /> </Window.Resources> 

Bind the checkmark to the ViewModels property, which will control the visibility of the columns.

 <CheckBox x:Name="DetailsVisible" Content="Show Details" IsChecked="{Binding Path=DisplayDetails}" /> 

Then bind the visibility to the ViewModels DisplayDetails property. Note that this is a column that is bound to a DataContext.

 <DataGridTextColumn Header="Reliability" Binding="{Binding Path=Reliability}" Visibility="{Binding (FrameworkElement.DataContext).DisplayDetails, RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource BoolToVisConverter}}"> </DataGridTextColumn> 

Add the following code to your project, this will catch the change in the DataCrtext DataGrids.

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

Then, whenever the DataContext DataGrids changes, we update all connected DataGridColumsn with the new DataContext.

 public static void OnDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { DataGrid grid = d as DataGrid; if (grid != null) { foreach (DataGridColumn col in grid.Columns) { col.SetValue(FrameworkElement.DataContextProperty, e.NewValue); } } } 

One Gotcha to look for. If you add your DataContext to your page as follows:

 <Window.DataContext> <vm:WeaponListViewModel /> </Window.DataContext> 

Then the above function will be called before your DataGrid has any columns!

I got around this by manually binding my DataConext to the code after creating the window.

+6
wpf xaml wpfdatagrid
source share
2 answers

The problem is that the DataGrid columns are not part of the visual tree, so they cannot use bindings. (The Binding property is actually a normal Binding property, not a dependency property. It applies this binding object to cells that are part of the visual tree.)

Here is a link to a blog with a workaround and demonstrates binding column visibility to a checkbox: http://blogs.msdn.com/b/jaimer/archive/2008/11/22/forwarding-the-datagrid-s-datacontext-to-its -columns.aspx

+2
source share

IMO using x:Name , x:Reference and Source simpler:

 <Window.Resources> <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> </Window.Resources> <CheckBox x:Name="showImperial" Content="Show Details" /> <DataGrid> <DataGrid.Columns> <DataGridTextColumn Header="TOV (Bls)" Width="80" Binding="{Binding TOVBarrels}" Visibility="{Binding Source={x:Reference showImperial}, Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}}"/> </DataGrid.Columns> </DataGrid> 

See this answer: The sign of binding to the checked menu item shows an error. "The service provider does not have the INameResolver service." in WPF

+1
source share

All Articles