RoutedCommand в ContextMenu в UserControl

Ситуация:

У меня есть статический RoutedCommand, определенный следующим образом:

public static class Commands
{
    public static readonly RoutedCommand GrowingOperation = new RoutedCommand("GrowingOperation", typeof(GrowingDisplay));
}

В моем MyUserControl.xaml я определяю команду следующим образом:

<UserControl.CommandBindings>
    <CommandBinding Command="{x:Static local:Commands.GrowingOperation}"
                    Executed="GrowingOperationExecuted"
                    CanExecute="GrowingOperationCanExecute"/>
</UserControl.CommandBindings>

А затем используйте это так в моем ContextMenu моего MyUserControl:

<UserControl.ContextMenu>
    <ContextMenu x:Name="GrowingContextMenu">
        <MenuItem Header="Grow"
                      Command="{x:Static local:Commands.GrowingOperation}"
                      CommandParameter="grow"/>
    </ContextMenu>
</UserControl.ContextMenu>

Проблема:

Появляется ContextMenu, но ни GrowingOperationExecuted, ни GrowingOperationCanExecute не вызываются. Я также не получаю никаких исключений при открытии файла ContextMenu.

Открытый ContextMenu выглядит так: введите здесь описание изображения

Вроде включено, но абсолютно никакого взаимодействия, даже анимации наведения. Где здесь ошибка?

ИЗМЕНИТЬ:

Здесь реализация методов команды:

    private void GrowingOperationExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        if (e.Parameter == null)
            throw new ArgumentException("ExecutedRoutedEventArgs must contain parameter.");
        var task = e.Parameter.ToString().ToLower();
        switch (task)
        {
            case "grow":
                Growing.SpeedUpGrowing();
                break;
            default:
                throw  new ArgumentOutOfRangeException();
        }
    }

    private void GrowingOperationCanExecute(object sender, CanExecuteRoutedEventArgs e)
    {
        if (e.Parameter == null)
            throw new ArgumentException("ExecutedRoutedEventArgs must contain parameter.");
        var task = e.Parameter.ToString().ToLower();
        switch (task)
        {
            case "grow":
                e.CanExecute = Growing.CanSpeedUpGrowing();
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

РЕДАКТИРОВАТЬ 2:

Конструктор моего MyUserControl:

public GrowingDisplay()
    {
        InitializeComponent();

        HeightProperty.AddOwner(typeof (GrowingDisplay),
                                new FrameworkPropertyMetadata(OnHeightPropertyChanged));
        WidthProperty.AddOwner(typeof (GrowingDisplay),
                               new FrameworkPropertyMetadata(OnWidthPropertyChanged));

        CommandManager.InvalidateRequerySuggested();
    }

person Herdo    schedule 05.07.2013    source источник


Ответы (2)


Я бы изменил определение вашего RoutedCommand на:

private static RoutedUICommand _GrowingOperation;
public static RoutedCommand GrowingOperation
{
    get
    {
        if(_GrowingOperation == null)
        {
            _GrowingOperation = new RoutedUICommand("GrowingOperation", 
                                "GrowingOperation", typeof(WINDOWNAME));
        }
        return _GrowingOperation;
}

Затем вы можете очистить свой XAML, добавив класс Commands с помощью:

xmlns:commands="clr-namespace:NAMESPACE.Commands"

Поместите это в открывающий тег окна. (Предполагая, что это окно). Затем, когда вы устанавливаете свою команду, вы можете использовать:

<UserControl.CommandBindings>
<CommandBinding Command="commands:Commands.GrowingOperation"
                Executed="GrowingOperationExecuted"
                CanExecute="GrowingOperationCanExecute"/>

Мой единственный вопрос: как вы реализуете GrowingOperationExecuted и GrowingOperationCanExecute?

person Th3BFG    schedule 05.07.2013
comment
Я реализую оба метода в коде моего MyUserControl, а затем использую этот пользовательский элемент управления в моем MainWindow. Пробую ваше решение... - person Herdo; 05.07.2013
comment
Если это не сработает, не могли бы вы опубликовать GrowingOperationCanExecute, чтобы убедиться, что оно реализовано правильно? - person Th3BFG; 05.07.2013
comment
В порядке. Вместо этого использовал ваши UICommands и очистил код XAML. До сих пор не работает. Как было сказано ранее, точка останова в методе даже не выполняется, но я опубликую оба метода выше. - person Herdo; 05.07.2013
comment
Вы сказали выше, что у вас нет анимации при наведении курсора на контекстное меню? Попробуйте запустить CommandManager.InvalidateQuerySuggested(); после заполнения ContextMenu. Кроме того, я заметил, что, возможно, я сделал ошибку. В определении RoutedCommand вместо typeof(WINDOWNAME) попробуйте typeof(Commands) - person Th3BFG; 05.07.2013
comment
Использовал typeof(Commands) уже. CommandManager.InvalidateRequerySuggested() как выше в редактировании 2? Не помогает... - person Herdo; 05.07.2013
comment
К вашему сведению: если я удалю команду из MenuItem в ContextMenu, эффект наведения снова сработает. - person Herdo; 06.07.2013

Этот пост должен помочь решить вашу проблему: http://wpftutorial.net/RoutedCommandsInContextMenu.html.

person B.S.    schedule 17.08.2013
comment
Такие ответы не приветствуются. Не размещайте ссылки на сообщения в блогах, содержащие ответ. ВАШ ответ должен быть последним пунктом исследования, которое кто-то должен провести. - person Manuel; 17.08.2013