WPF Data Grid Tips

While working on WPF, I came to know some good Data grid tips and wanted to share you the same.

Issue

WPF Data Grid is not reflecting the changed Item Source.

Solution

If using MVVM pattern, Refresh the item source by below command.

CollectionViewSource.GetDefaultView(<Your Data Grid collection name>).Refresh();

Issue

How to open a context menu from data grid and assign event handler after clicking on menu item.

Solution

Step A: create context menu by inserting the following code.

<Window.Resources>

<ContextMenu x:Key="mnuAddList" Name="mnuAddList">

<MenuItem Name="mnuAdd" Header="Edit" Command="{Binding PopUpAddCommand}">

</MenuItem>

</ContextMenu>

</Window.Resources>

Please note that here Context menu key (i.e. mnuAddList) will be used to attach with data grid in the next step. Also PopUpAddCommand is a property (defined in View Model) of DelegateCommand type which will have reference of event handler.

Step B: Attach the menu created in step 1 with grid.

<DataGrid Name="grdAdd" ContextMenu ="{StaticResource mnuAddList}" >

Issue

Visibility property is not setting for Grid column and by doing so getting error as "System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=IsMyColumnVisibile; DataItem=null; target element is'DataGridTextColumn' (HashCode=7395880); target property is 'Visibility' (type'Visibility')"

Solution

DataGridColumns are not part of visual tree so they are not connected to the data context of the DataGrid due to that their visibility binding can't be done straight forward. To achieve this, following steps needs to performed.

  1. Add a proxy FrameworkElement in your ancestor panel's Resources.
  2. Host it into an invisible ContentControl bound to its Content.
  3. Use this ProxyElement as StaticResource for data context source in your visibility binding.

Code snippet

<StackPanel>

  <StackPanel.Resources>

    <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />

    <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/>

  </StackPanel.Resources>

  <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"/>

  <DataGrid AutoGenerateColumns="False">

    <DataGrid.Columns>

      <DataGridTextColumn Visibility="{Binding DataContext.IsMyColumnVisibile, Source={StaticResource ProxyElement}, Converter={StaticResource BooleanToVisibilityConverter}}" Binding="{Binding MyColumn}"/>

    </DataGrid.Columns>

  </DataGrid>

</StackPanel>