Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this WPF RoutedCommand bound Context MenuItem disabled?

Tags:

menuitem

wpf

I'm still fumbling my way around WPF at the moment, and can not figure out why this context menu item is disabled:

<Window x:Class="DisabledMenuItemProblem.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DisabledMenuItemProblem"
        Title="Window1" Height="300" Width="300">
    <TextBlock Text="fooooobaaaaaar">
        <TextBlock.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Foo" Command="{x:Static local:MyCommands.FooBar}" />
            </ContextMenu>
        </TextBlock.ContextMenu>
    </TextBlock>
</Window>

using System.Windows;
using System.Windows.Input;

namespace DisabledMenuItemProblem
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            CommandBindings.Add(new CommandBinding(MyCommands.FooBar, FooExecuted, CanFooExecute));
        }

        public void FooExecuted(object sender, ExecutedRoutedEventArgs e)
        { MessageBox.Show("Foo!"); }

        public void CanFooExecute(object sender, CanExecuteRoutedEventArgs e)
        { e.CanExecute = true; }
    }

    public static class MyCommands
    { 
        public static RoutedCommand FooBar = new RoutedCommand(); 
    }
}

What am i missing?

What's also baffling me is that if i throw a button in the window and set its command to FooBar it works, and once its been executed, then the context menu gets enabled!

Cheers guys, Chris.

like image 242
Chris Browne Avatar asked Jan 18 '09 17:01

Chris Browne


1 Answers

here is the general pattern that I use....

first, keep your commands in thier own static class, this promotes reuse,etc....

public static class MyCommands
{
    public static RoutedUICommand CmdFoo = new RoutedUICommand("CmdFoo", 
                                                               "CmdFoo", 
                                                               typeof(MyCommands));
}

second, register the command in the control/window/etc. you want to use it in, normally in the constructor

public MyControl
{
    public MyControl()
    {
        CommandBindings.Add( 
            new CommandBinding( MyCommands.CmdFoo,   // this is the command object
                                XCutFooCommand,      // execute
                                CanXCuteFooCommand));// can execute?
    }

third, create your handlers in the control/window/etc.....

  public void CanExecuteRerollCommand(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = true;  // can this command be executed?
        e.Handled = true;     // has this event been handled?
    }
    public void ExecuteRerollCommand(object sender, ExecutedRoutedEventArgs e)
    {
    // do stuff
    }
}

lastly, your xaml ought to look like this:

    <ContextMenu>
        <ContextMenu.CommandBindings>
            <CommandBinding Command="foo:MyCommands.CmdFoo" 
                            CanExecute="CanExecuteRerollCommand" 
                            Executed="ExecuteRerollCommand" />
        </ContextMenu.CommandBindings>
        <MenuItem Header="Reroll"  Command="foo:MyCommands.CmdFoo"/>
    </ContextMenu>

notice that there is no binding. Also, notice the <CommandBinding> in the <ContextMenu>. here is a reference.... http://www.wiredprairie.us/journal/2007/04/commandtarget_menuitem_context.html

the command being disabled is addressed at this site

like image 135
Muad'Dib Avatar answered Sep 22 '22 13:09

Muad'Dib