WPF Data Grid tips

Hi folks,

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> 

Appreciate your comments!