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
FYI: Ако премахна командата от 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