Martin
Martin

Reputation: 111

contextmenu won't open anymore on datagrid after several updates

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

Answers (1)

Rekshino
Rekshino

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

Related Questions