Reputation: 111
I have a wpf datagrid, by a template I create a contextmenu for every row. Since the grid rows are getting constantly changed it often happens that the contextmenu gets closed when the focused row disappears.
After a while the contextmenu won't open anymore on the entire grid. It happens if the contextmenu is heavily used and there are lots of updates. I tried to debug this by logging the ContextMenuOpening, contextMenuClosing and MouseRightButtonDown events. The "opening" gets raised but the menu isn't visible. Reopening the window clears the issue.
Currently I am at odds. Can somebody give me some pointers on how to resolve this issue? Perhaps somebody could recommend some XAML optimization. In the .cs file there is no interaction with the contextmenu, just adding and removing of the rows and some view-refresh (to update the grouping). The events are just for logging.
The ressource part
<Window.Resources>
<local:NegativeColorConverter x:Key="NegativeColorConverter"/>
<local:AllJobs x:Key="jobs"/>
<CollectionViewSource x:Name="cvsAllJobs" x:Key="cvsJobs" Source="{StaticResource jobs}" IsLiveGroupingRequested="True" IsLiveSortingRequested="True" CollectionViewType="ListCollectionView">
<CollectionViewSource.LiveGroupingProperties>
<s:String>omitted</s:String>
</CollectionViewSource.LiveGroupingProperties>
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription PropertyName="omitted"/>
</CollectionViewSource.GroupDescriptions>
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="GroupSort"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</Window.Resources>
And the grid
<DataGrid
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
x:Name="gridJobs"
CanUserSortColumns="False"
IsReadOnly="True"
CanUserDeleteRows="False"
CanUserAddRows="False"
GridLinesVisibility="Horizontal"
DragEnter="gridJobs_DragEnter"
Drop="gridJobs_Drop"
AllowDrop="True"
AutoGenerateColumns="False"
Margin="10"
SelectedItem ="{Binding SelectedRow, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
ItemsSource="{Binding Source={StaticResource cvsJobs}}"
HorizontalGridLinesBrush="Transparent"
PreviewKeyDown="gridJobs_PreviewKeyDown"
ContextMenuClosing="gridJobs_ContextMenuClosing"
ContextMenuOpening="gridJobs_ContextMenuOpening"
MouseRightButtonDown="gridJobs_MouseRightButtonDown"
>
<DataGrid.Resources>
<tools:BindingProxy x:Key="proxy" Data="{Binding}" />
<ContextMenu StaysOpen="True" x:Key="Jobs" ItemsSource="{Binding MenuItems}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Command" Value="{Binding Command}" />
<Setter Property="IsEnabled" Value="{Binding Enabled}" />
</Style>
</ContextMenu.ItemContainerStyle>
<ContextMenu.ItemTemplate>
<HierarchicalDataTemplate DataType="MenuItemViewModel" ItemsSource="{Binding MenuItems}">
<TextBlock Text="{Binding Header}"/>
</HierarchicalDataTemplate>
</ContextMenu.ItemTemplate>
</ContextMenu>
</DataGrid.Resources>
Columns omitted
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="FontFamily" Value="Calibri"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<!--<Setter Property="Background" Value="Black"/>-->
<Setter Property="Background" Value="{Binding BrushState, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource NegativeColorConverter}}"/>
<Setter Property="Foreground" Value="{Binding BrushState, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
</Trigger>
</Style.Triggers>
</Style>
</DataGrid.CellStyle>
<DataGrid.RowStyle>
<Style TargetType="DataGridRow" >
<Setter Property="ContextMenu" Value="{StaticResource Jobs}" />
<Setter Property="Foreground" Value="{Binding BrushState, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<Setter Property="Margin" Value="10,0,0,0"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="Height" Value="20"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
</DataGrid.RowStyle>
<DataGrid.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<DockPanel Background="Gray" Height="1">
</DockPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</DataGrid.GroupStyle>
</DataGrid>
Upvotes: 1
Views: 333
Reputation: 7325
Add to the ContextMenu
tag an attribute x:Shared="false"
, this will create an own ContextMenu
for each row. So it should work I think.
<ContextMenu StaysOpen="True" x:Key="Jobs" ItemsSource="{Binding MenuItems}" x:Shared="false">
Upvotes: 1