AvalonDock + UserControl + DataGrid + ContextMenu проблема маршрутизации команд - PullRequest
3 голосов
/ 14 мая 2010

Я получаю странное поведение при распространении команд из MenuItems из ContextMenu.

У меня есть следующий вид макета: ContextMenu установлен для каждого DataGridRow из DataGrid внутриUserControl, который в свою очередь находится внутри DockableContent AvalonDock.Если я избавлюсь от или стыковки или UserControl вокруг моей сетки, проблем не будет.ListBox вместо DataGrid также не имеет этой проблемы.

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

Так что вот в чем проблема: щелчок правой кнопкой мышив выбранной строке (если она была выбрана до щелчка правой кнопкой мыши) моя команда выходит отключенной.В данном случае это команда «Zoom», но может быть любой другой, включая пользовательскую.

Я не знаю, в чем здесь вина.SNOOP показывает, что в случаях, когда это распространение не удается, вместо UserControl, CanExecute обрабатывается "PART_ShowContextMenuButton" (Button), которая является частью заголовка стыковки.

У меня были другие проблемы с пользовательским интерфейсомРаспространение команд в UserControls, размещенном внутри AvalonDock, но этот самый простой для воспроизведения.

1 Ответ

2 голосов
/ 21 мая 2010

ContextMenu - это всплывающее окно, и поэтому для свойства привязанного FocusScope установлено значение true:

С MSDN

Область фокуса - это элемент контейнера. который отслеживает FocusManager .. ::. FocusedElement внутри его сфера применения. По умолчанию окно класс является областью фокуса, как и Меню, ContextMenu и Панель инструментов классы. Элемент, который является фокусом для свойства IsFocusScope установлено значение false.

По сути, он также указывает командам прекратить поиск в дереве визуалов.

Итак, у вас есть два варианта

  1. Установите FocusManager.IsFocusScope="True" для вашего объекта контекстного меню

  2. Или переместите привязки команд так, чтобы они были связаны с ContextMenu вместо UserControl следующим образом:

Пример кода:

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

Надеюсь, это поможет! :)

Некоторые кошмарные сказки FocusScope с полей на паутинах:

...