c# - 在 WPF 中打开 ContextMenu 时保留 DataGrid IsSelectionActive?

标签 c# wpf contextmenu wpfdatagrid css-selectors

我有一个 DataGrid,它的样式为 IsSelectionActive;然而,一旦 ContextMenu 打开,网格就会丢失 IsSelectionActive 并且在用户看来好像是上下文菜单以某种方式进行了选择并且可能会使用户感到困惑。

有没有办法在上下文菜单打开时保留 IsSelectionActive

<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>

最佳答案

这是我在测试应用程序中用于获得所需行为的完整 XAML:

<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>

启用此行为的关键是,如果具有冲突 Setter 的多个触发器同时处于事件状态,则最后一个获胜。

关于c# - 在 WPF 中打开 ContextMenu 时保留 DataGrid IsSelectionActive?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10775675/

相关文章:

c# - 使用 Microsoft.Azure.Storage.Common 9.4.0.2-preview 测试 Azure 表存储

c# - 在桌面应用程序的发布版本中分发 PDB 文件的优缺点

wpf - 减慢鼠标速度

c# - 默认 TabItem 背景颜色

java - 如何制作横向的上下文菜单?

c# - C# const 成员如何在内存中分配?

c# - WPF MVVM 应用程序中常量(标签文本等)应该放在何处

c# - RelayCommand 未触发 MenuItem 单击 WPF MVVM

jQuery 上下文菜单与 jQuery Draggable 冲突

eclipse-plugin - 如何将弹出菜单的可见性仅限于特定项目类型?