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.
- Add a proxy FrameworkElement in your ancestor panel's Resources.
- Host it into an invisible ContentControl bound to its Content.
- 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>