3

我从MenuItemsof 的命令传播中得到了奇怪的行为ContextMenu

我有以下类型的布局:ContextMenu为每个inside设置,DataGridRow而后者又位于AvalonDock 内部。如果我摆脱停靠或围绕我的网格,就没有问题。而不是也没有这个问题。DataGridUserControlDockableContentUserControlListBoxDataGrid

<Window x:Class="DockAndMenuTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ad="clr-namespace:AvalonDock;assembly=AvalonDock"
        Title="MainWindow" Height="350" Width="525">
    <ad:DockingManager>
        <ad:DocumentPane>
            <ad:DockableContent Title="Doh!">
                <UserControl>
                    <UserControl.CommandBindings>
                        <CommandBinding Command="Zoom" 
                                        Executed="ExecuteZoom" 
                                        CanExecute="CanZoom"/>
                    </UserControl.CommandBindings>
                    <DataGrid Name="_evilGrid">
                        <DataGrid.Resources>
                            <Style TargetType="DataGridRow">
                                <Setter Property="ContextMenu">
                                    <Setter.Value>
                                        <ContextMenu>
                                            <MenuItem Command="Zoom"/>
                                        </ContextMenu>
                                    </Setter.Value>
                                </Setter>
                            </Style>
                        </DataGrid.Resources>
                    </DataGrid>
                </UserControl>
            </ad:DockableContent>
        </ad:DocumentPane>
    </ad:DockingManager>
</Window>

代码隐藏也很简单:

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();

        _evilGrid.ItemsSource =
            new[]
                {
                    Tuple.Create(1, 2, 3),
                    Tuple.Create(4, 4, 3),
                    Tuple.Create(6, 7, 1),
                };
    }

    private void ExecuteZoom(object sender, ExecutedRoutedEventArgs e)
    {
        MessageBox.Show("zoom !");
    }

    private void CanZoom(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;
    }
}

所以这就是问题所在:右键单击选定的行(如果它在右键单击之前被选中)我的命令被禁用。在这种情况下,命令是“缩放”,但可以是任何其他命令,包括自定义命令。

我不知道这里有什么问题。SNOOP 表明,在此传播失败的情况下,由“PART_ShowContextMenuButton”(按钮)处理,而不是UserControlCanExecute它是对接标头的一部分。

UserControls在 AvalonDock 内托管的 UI 命令传播方面遇到了其他问题,但这是最容易重现的问题。

4

1 回答 1

2

ContextMenu 是一个弹出窗口,因此它的 FocusScope 附加属性设置为 true:

来自MSDN

焦点范围是一个容器元素,它在其范围内跟踪 FocusManager..::.FocusedElement。默认情况下,Window 类是焦点范围,Menu、ContextMenu 和 ToolBar 类也是如此。作为焦点范围的元素将 IsFocusScope 设置为 false。

基本上,它还告诉命令停止在可视化树中进一步查看。

所以你有两个选择

  1. FocusManager.IsFocusScope="True"在上下文菜单对象上设置

  2. 或者移动您的 Command 绑定,以便您绑定到 ContextMenu 而不是 UserControl,如下所示:

代码示例:

<ContextMenu FocusManager.IsFocusScope="False">
    <ContextMenu.CommandBindings>
        <CommandBinding Command="Zoom" 
                Executed="ExecuteZoom" 
                CanExecute="CanZoom"/>
    </ContextMenu.CommandBindings>
         <MenuItem Command="Zoom"/>
</ContextMenu>

希望这可以帮助!:)

一些来自互联网领域的 FocusScope 噩梦故事:

于 2010-05-21T13:33:09.760 回答