Retain DataGrid IsSelectionActive when a ContextMe

2019-04-06 10:37发布

I have a DataGrid which has a style for IsSelectionActive; however, as soon as the ContextMenu opens, the grid loses IsSelectionActive and it looks like to the user that as if the context menu somehow took the selection and may confuse the user.

Is there a way to retain IsSelectionActive when a context menu opens?

<ControlTemplate.Triggers>
    <MultiTrigger>
        <MultiTrigger.Conditions>
            <!--<Condition Property="Selector.IsFocused" Value="True" />-->
            <Condition Property="IsSelected" Value="True" />
        </MultiTrigger.Conditions>

        <Setter Property="Background" Value="Red" />
    </MultiTrigger>

    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="Selector.IsFocused" Value="False" />
            <Condition Property="IsSelected" Value="False" />
        </MultiTrigger.Conditions>

        <Setter Property="Background" Value="Green" />
    </MultiTrigger>

    <MultiTrigger>
        <MultiTrigger.Conditions>
            <Condition Property="Selector.IsFocused" Value="False" />
            <Condition Property="IsSelected" Value="True" />
        </MultiTrigger.Conditions>

        <Setter Property="Background" Value="Blue" />
    </MultiTrigger>

1条回答
仙女界的扛把子
2楼-- · 2019-04-06 11:11

Here is an entire XAML that I used in test application to get your desired behavior:

<Window x:Class="DataGridSelectionActive.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DataGridSelectionActive"
        Title="MainWindow" Height="350" Width="525">

    <!-- People is just an ObservableCollection derived class. -->
    <Window.DataContext>
        <local:People/>
    </Window.DataContext>

    <Window.Resources>

        <ContextMenu x:Key="dataGridContextMenu">
            <MenuItem Header="Some context menu item"/>
        </ContextMenu>

        <Style TargetType="{x:Type DataGridCell}">
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                </Trigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True"/>
                        <Condition Binding="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource AncestorType=DataGrid}}" Value="False"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
                </MultiDataTrigger>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="True"/>
                        <Condition Binding="{Binding ContextMenu.IsOpen, RelativeSource={RelativeSource AncestorType=DataGrid}}" Value="True"/>
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                    <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
                    <Setter Property="BorderBrush" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>

    </Window.Resources>

    <DockPanel>
        <!-- Added button for testing keyboard focus. -->
        <Button DockPanel.Dock="Top" Content="Click me"/>
        <DataGrid ItemsSource="{Binding}" ContextMenu="{StaticResource dataGridContextMenu}"/>
    </DockPanel>

</Window>

The key thing that enables this behavior is that if multiple triggers that have conflicting Setters are active simultaneously, the last one wins.

查看更多
登录 后发表回答