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

Posted

技术标签:

【中文标题】在 WPF 中打开 ContextMenu 时保留 DataGrid IsSelectionActive?【英文标题】:Retain DataGrid IsSelectionActive when a ContextMenu opens in WPF? 【发布时间】:2012-06-02 06:59:10 【问题描述】:

我有一个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>

【问题讨论】:

请使用 IsSelectionActive 提供您的样式代码。 【参考方案1】:

这是我在测试应用程序中使用的完整 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>

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

【讨论】:

以上是关于在 WPF 中打开 ContextMenu 时保留 DataGrid IsSelectionActive?的主要内容,如果未能解决你的问题,请参考以下文章

WPF:如何设置或禁用 TextBox 的默认 ContextMenu

虚拟化ListBox ContextMenu XamlParseException

WPF:在 Expression Blend 4 中编辑 ContextMenu 或 ToolTip:错误“不能有逻辑或可视父级”。

WPF 左键单击弹出菜单 ContextMenu

WPF ContextMenu 在MVVM模式中无法绑定 Command的解决办法

WPF ContextMenu 在MVVM模式中绑定 Command及使用CommandParameter传参