Question

Situation:

I have a static RoutedCommand defined like this:

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

In my MyUserControl.xaml I define the command like this:

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

And then use it like this in my ContextMenu of my MyUserControl:

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

Issue:

The ContextMenu appears, but neither the GrowingOperationExecuted nor the GrowingOperationCanExecute get called. Neither do I get any exception when opening the ContextMenu.

The open ContextMenu looks like this: enter image description here

It seems to be enabled, but there is absolute no interaction, not even a hover animation. Where is the error here?

EDIT:

Here the implementation of the command methods:

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

EDIT 2:

The constructor of my MyUserControl:

public GrowingDisplay()
    {
        InitializeComponent();

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

        CommandManager.InvalidateRequerySuggested();
    }
Was it helpful?

Solution

I would change the definition of your RoutedCommand to:

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

Then you can clean up your XAML by bringing the Commands class in with:

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

Put this in the opening Window tag. (Assuming this is a Window) Then when you set your command you can use:

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

My only question is this: How are you implementing GrowingOperationExecuted and GrowingOperationCanExecute?

OTHER TIPS

This post should be helpful for solving your problem: http://wpftutorial.net/RoutedCommandsInContextMenu.html.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top