Defining MenuItem Shortcuts - wpf

I need a simple way to set a shortcut for menu items.
But this donĀ“t work with shortcut, just with click:
<MenuItem Header="Editar">
<MenuItem Header="Procurar" Name="MenuProcurar"
InputGestureText="Ctrl+F"
Click="MenuProcurar_Click">
<MenuItem.ToolTip>
<ToolTip>
Procurar
</ToolTip>
</MenuItem.ToolTip>
</MenuItem>
</MenuItem>
I am using WPF 4.0

H.B. was right... I just wanted to add more precisions.
Remove the Click event on your MenuItem and associate it with a Command instead.
1 - Add/create your commands:
<Window.CommandBindings>
<CommandBinding Command="Open" Executed="OpenCommandBinding_Executed"/>
<CommandBinding Command="SaveAs" Executed="SaveAsCommandBinding_Executed"/>
</Window.CommandBindings>
The commands are refering to the following code:
private void OpenCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
Open();//Implementation of open file
}
private void SaveAsCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
SaveAs();//Implementation of saveAs
}
2 - Associate the commands with the wanted keys:
<Window.InputBindings>
<KeyBinding Key="O" Modifiers="Control" Command="Open"/>
<KeyBinding Key="S" Modifiers="Control" Command="SaveAs"/>
</Window.InputBindings>
3 - Finally assign the commands with you menu item (InputGestureText is just a decorating text):
<Menu Name="menu1">
<MenuItem Header="_File">
<MenuItem Name="menuOpen" Header="_Open..." Command="Open" InputGestureText="Ctrl+O"/>
<MenuItem Name="menuSaveAs" Header="_Save as..." Command="SaveAs" InputGestureText="Ctrl+S"/>
</MenuItem>
</Menu>
That way multiple inputs may be associated to the same command.

You need to use KeyBindings (and CommandBindings if you (re)use RoutedCommands such as those found in the ApplicationCommands class) for that in the controls where the shortcuts should work.
e.g.
<Window.CommandBindings>
<CommandBinding Command="New" Executed="CommandBinding_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="N" Modifiers="Control" Command="New"/>
</Window.InputBindings>
For custom RoutedCommands:
static class CustomCommands
{
public static RoutedCommand DoStuff = new RoutedCommand();
}
usage:
<Window
...
xmlns:local="clr-namespace:MyNamespace">
<Window.CommandBindings>
<CommandBinding Command="local:CustomCommands.DoStuff" Executed="DoStuff_Executed" />
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="D" Modifiers="Control" Command="local:CustomCommands.DoStuff"/>
</Window.InputBindings>
...
</Window>
(It is often more convenient to implement the ICommand interface rather than using RoutedCommands. You can have a constructor which takes delegates for Execute and CanExecute to easily create commands which do different things, such implementations are often called DelegateCommand or RelayCommand. This way you do not need CommandBindings.)

In my humble opinion is much easier just to use _ at the Header. This will create automatically the desired HotKey.
For example:
<MenuItem Header="_Editar">
<MenuItem Header="_Procurar" Name="MenuProcurar"
InputGestureText="Ctrl+F"
Click="MenuProcurar_Click">
<MenuItem.ToolTip>
<ToolTip>
Procurar
</ToolTip>
</MenuItem.ToolTip>
</MenuItem>
</MenuItem>

I'm overly biased by Windows.Forms & gulp VB 6, so I kind of agree with Jonathan and Jase that there's got to be a more straightforward/procedural method to statically wire up event handlers that aren't necessarily CommandBindings. And there is, I think.
A good tutorial for using non-CommandBinding handlers like this, but with an emphasis on buttons, can be found in this MSDN blog post, I believe. I'll distill and target MenuItems...
Creating the ICommand
First, create a class implementing ICommand. You can put this anywhere, of course, even in your MainWindow.xaml.cs file if you wanted, to keep your demo code insanely simple. You'll probably want to make CanExecute more complicated when you want to dis/en/able menu items later, but for now, we'll just always have our menu items enabled.
public class HelloWorldCommand : ICommand
{
public void Execute(object parameter)
{
MessageBox.Show(#"""Hello, world!"" from "
+ (parameter ?? "somewhere secret").ToString());
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
}
As the tutorial helpfully points out, you could call this command from anywhere already, with code like...
var hwc = new HelloWorldCommand();
if (hwc.CanExecute(this))
hwc.Execute(this);
Declaring your command in the Window
So let's add a sort of "declaration" for the HelloWorldCommand to our Window so that we can use it later. Inside of your Window tags, register the command as a resource:
<Window.Resources>
<local:HelloWorldCommand x:Key="hwc"/>
</Window.Resources>
Now we have a neat shortcut for linking to this "locally namespaced" command, "hwc", though you can obviously use any string you want. We'll use that a lot in our xaml.
Wiring up (and reusing!) the command
Let's add our MenuItems to our xaml. I've replaced the stock Grid with a DockPanel because that's the easiest way (for me) to have equi-spaced widgets that fill the Window, though I've left all of the rest of my UI out.
Note the Command="{StaticResource hwc}"s sprinkled into each MenuItem declaration. The key is the hwc in there - remember that that's our shortcut for the HelloWorldCommand that we set up at the Window level. And, of course, StaticResource says just to look it up the Window's resources. We're not binding anything; we're just using our shortcut.
<DockPanel LastChildFill="True">
<Menu DockPanel.Dock="Top">
<MenuItem Header="_File">
<MenuItem
Header="_Open"
Command="{StaticResource hwc}"
>
<MenuItem.CommandParameter>
<!-- so you could make this object as complex as you wanted,
like, say, your entire Window. See magic incantation, below. -->
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType=Window}" />
</MenuItem.CommandParameter>
</MenuItem>
<MenuItem
Header="_Close"
Command="{StaticResource hwc}"
CommandParameter="Close"
InputGestureText="Ctrl+G" />
<MenuItem
Header="_Save"
Command="{StaticResource hwc}"
CommandParameter="Save" />
<Separator />
<MenuItem
Header="_Quit"
Command="{StaticResource hwc}"
CommandParameter="Quit" />
</MenuItem>
</DockPanel>
CommandParameters to distinguish event sources
Note that we're using the same Command for everything! But how can we tell which widget threw the event? For that, you need to use the CommandParameter -- remember our Execute method's signature: Execute(object parameter). That CommandParameter parameter is what we can use to know how to handle the event. Try running this and note that the MessageBox will use whatever's in CommandParameter to let you know the source of the event. We're doing it all manually, but that's not too bad.
Also note that you can make these objects as complicated as you'd like. You can use a property in the MenuItem tag to define the parameter, or can use "real" <MenuItem.CommandParameter> tags, like in the Open menu item, above, to define something complex. In this case, we're passing the entire parent Window object, which was the easiest (though not the cleanest) way to throw our VB6-ish context into the event handler code.
Adding keyboard shortcuts to MenuItems (aka, "Answering the OP")
And now we can finally answer the original question! Let's finally wire up a keyboard shortcut for the Close menu item. You'll note that we've already declared an InputGestureText. By itself, InputGestureText is only cosmetic. If we were overly picky, we could argue the mechanism for creating the keyboard shortcut doesn't have any direct, inherent relationship with the MenuItem at all!
We need to instead (or additionally) register a listener for Ctrl-G at the Window level to catch the keystroke. So at the top level of your Window tags, insert this (taken essentially from here):
<Window.InputBindings>
<KeyBinding Modifiers="Control"
Key="G"
Command="{StaticResource hwc}"
CommandParameter="window input binding"
/>
</Window.InputBindings>
Note that you could put CommandParameter tags in your KeyBinding by moving it from a self-closing piece of XML to "real" open and close KeyBinding tags.
And we're done. Run your app, and press Ctrl-G. Whaddup.
Pretty straightforward, once you've got the players straight, and much less magic binding-y than most intros to commands and MenuItems, I think.
Possible pro tip:
The whole CommandBinding thing confused me for a while. This is just for specific command types, I believe. That is, you can't just wire up any Command you like. Stuff like what's bragged about here (in what's admittedly a decent intro tutorial!)...
It might not be completely obvious, but by using commands, we just got a whole bunch of things for free: Keyboard shortcuts, text and InputGestureText on the items and WPF automatically enables/disables the items depending on the active control and its state. In this case, Cut and Copy are disabled because no text is selected, but Paste is enabled, because my clipboard is not empty!
... is kind of magic-y and not necessarily good, and can be confusing when you're new to WPF menus.

You can also declare RoutedUICommand in XAML:
<Window.Resources>
<RoutedUICommand x:Key="BuildCmd" Text="Build">
<RoutedUICommand.InputGestures>
<KeyGesture>CTRL+SHIFT+B</KeyGesture>
</RoutedUICommand.InputGestures>
</RoutedUICommand>
</Window.Resources>
Do the binding
<Window.CommandBindings>
<CommandBinding Command="{StaticResource BuildCmd}" Executed="BuildCmdExecuted"/>
</Window.CommandBindings>
And in MenuItem
<MenuItem Command="{StaticResource BuildCmd}"/>
Another solution is discussed here.

Here is solution in PowerShell:
Define your XAML file:
<Window x:Class="WpfApp1.Window1"
xmlns:local="clr-namespace:WpfApp1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="My App" Height="620" Width="950" >
<Window.InputBindings>
<KeyBinding Key="S" Modifiers="Ctrl"/>
</Window.InputBindings>
<Grid x:Name="MainGrid">
<!--Your GUI is here-->
<Menu Margin="0">
<MenuItem Header="_File">
<MenuItem x:Name="SaveProfile" Header="_Save Profile" InputGestureText="Ctrl+S"/>
</MenuItem>
</Menu>
</Grid>
</Window>
Add new type to be able to create Command(s)
Add-Type #"
public class DelegateCommand : System.Windows.Input.ICommand
{
private System.Action<object> _action;
public DelegateCommand(System.Action<object> action)
{
_action = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public event System.EventHandler CanExecuteChanged = delegate { };
public void Execute(object parameter)
{
_action(parameter);
}
}
"#
Create and assign new Command to the previously defined KeyBinding, it is first key binding, that is why I'm addressing it with [0].
Note:in my case I saved the handle to the main Window in $hash.Window variable, you should put here the link to your main window object, that you created with [Windows.Markup.XamlReader]::Load($xamlXmlNodeReader) command or other window creation command.
$hash.Window.InputBindings[0].Command = New-Object DelegateCommand( { Save-Profile } )
Create your function that you put into command
function Save-Profile {
Write-Host "Save Profile"
# Your logic goes here
}
Thanks to Nicholas Wolverson for the tips on how to create the Type for Command.

This work for me
<ContextMenu PreviewKeyUp="ContextMenu_PreviewKeyUp">
<MenuItem Header="Delete" Click="DeleteID" />
</ContextMenu>
Code behind:
private void ContextMenu_PreviewKeyUp(object sender, KeyEventArgs e)
{
ContextMenu contextMenu = sender as ContextMenu;
if (e.Key == Key.D)
{
//DELETE ID
}
contextMenu.IsOpen = false;
}

Related

What can break WPF CommandBindings on a MenuItem?

I have some CommandBindings (in a Window) that work with MenuItems (by "work" I mean the executed/canexecute handlers are called),
I have others (in a UserControl) that work when assigned to the Command properties of Buttons (the handlers are called) -- but not when used with MenuItems (the handlers are never called).
I can make a MenuItem interact correctly with a CommandBinding in the UserControl by copying and pasting each binding into the appropriate MenuItem.CommandBindings, like so:
<MenuItem
Header="Select All"
Command="{StaticResource SelectAllCommand}"
>
<MenuItem.CommandBindings>
<CommandBinding
Command="{StaticResource SelectAllCommand}"
Executed="SelectAll_Executed"
CanExecute="SelectAll_CanExecute"
/>
</MenuItem.CommandBindings>
</MenuItem>
But that's silly (and see below).
I can also make them work by copying the UserControl's command bindings up to the window in the UserControl's constructor:
C#
Application.Current.MainWindow.CommandBindings.AddRange(this.CommandBindings);
Again, that's pretty crazy, but it does seem to imply that there's a contextual factor at work here.
I copied the relevant bits of the control XAML into the following test XAML to reproduce the issue, but the issue didn't reproduce. Unlike the production code I extracted it from, it works as you'd expect: It's a binding, it's bound, it calls the methods. But the exact same method of binding event handler methods to commands to menuitems fails in a different UserControl in a different (and incompably vaster and more complicated) project.
XAML:
<UserControl
x:Class="CommandTest.TestControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
>
<UserControl.Resources>
<ResourceDictionary>
<RoutedUICommand x:Key="TestCommand" />
<ContextMenu x:Key="TestMenu">
<MenuItem
Header="_Test"
Command="{StaticResource TestCommand}"
/>
</ContextMenu>
</ResourceDictionary>
</UserControl.Resources>
<UserControl.CommandBindings>
<CommandBinding
Command="{StaticResource TestCommand}"
Executed="TestCommand_Executed"
CanExecute="TestCommand_CanExecute"
/>
</UserControl.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBox
Width="200"
ContextMenu="{StaticResource TestMenu}"
/>
</Grid>
</UserControl>
C#:
private void TestCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Test Command", "Test", MessageBoxButton.OK,
MessageBoxImage.Information);
}
private void TestCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
e.Handled = true;
}
So the question is, what hidden factors can cause a CommandBinding to fail silently? How do you even debug this? Why would I see completely different behavior between a Button and a MenuItem for the same command binding in the same control? Is it because the ContextMenu is a resource? But in my test code, it's a resource and everything works.
UPDATE:
Another solution^Wworkaround: Explicitly set the MenuItem.PlacementTarget to the ContextMenu. Huh.
I suspect there is a subtle difference between the visual trees of your test project and your production project that is interfering with the command routing. Routed Commands search for command handlers along the visual tree, and up to two paths may be taken.
From this MSDN Magazine article:
Usually, a command invoker looks for a command binding between its own location in the visual tree and the root of the visual tree. If it finds one, the bound command handler will determine whether the command is enabled and will be called when the command is invoked. If the command is hooked up to a control inside a toolbar or menu (or, more generally, a container that sets FocusManager.IsFocusScope = true), then some additional logic runs that also looks along the visual tree path from the root to the focus element for a command binding.

Assign shortcut key in WPF Ribbon Button

I have a WPF Ribbon Button and I want it to have a shortcut key. (e.g. Ctrl+A). Been searching in google but lost to get a possible answer. Does anyone knows how I might deal with this? Thanks =)
Here is what I have so far
<my:RibbonButton Name="rb1" Content="Images/save.png" />
<my:RibbonButton Name="rb2" Content="Images/abort.png" />
you may perhaps use UIElement.InputBindings with KeyBinding
example
<Window.InputBindings>
<KeyBinding Key="S"
Modifiers="Control"
Command="{Binding Save}" />
<KeyBinding Key="A"
Modifiers="Control"
Command="{Binding Abort}" />
</Window.InputBindings>
using this approach you can bind the input gestures to the commands which buttons are using
assumed code
<my:RibbonButton Name="rb1" Content="Images/save.png" Command="{Binding Save}" />
<my:RibbonButton Name="rb2" Content="Images/abort.png" Command="{Binding Abort}" />
from MSDN: KeyBinding
A KeyBinding associates a KeyGesture with a ICommand, such as a RoutedCommand. RoutedCommand is the primary implementation of the ICommand interface for the WPF commanding system . In general, when the KeyGesture is executed the command is invoked, although the command behavior is further influenced by command-specific factors such as the CanExecute value.
I prefer doing it in code behind. I am using the code in my program.
Hope it help.
private void AddHotKeys()
{
try
{
RoutedCommand firstHotkey = new RoutedCommand();
firstHotkey .InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Alt));
CommandBindings.Add(new CommandBinding(firstHotkey , Save));
}
catch (Exception err)
{
//handle exception error
}
}

In XAML is it possible to use an ElementName binding before the element it refers to is declared?

I have a UserControl with some InputBindings. I wanted to make one of the input bindings (arrow key press) execute a command on a GUI control in my UserControl . So
e.g.
<UserControl.InputBindings>
<KeyBinding Key="Up" Command="{Binding ElementName=MyViewElement, Path=MoveUpCommand}"/>
<KeyBinding Key="Down" Command="{Binding ElementName=MyViewElement, Path=MoveDownCommand}"/>
</UserControl.InputBindings>
But, this fails because MyViewElement is not found because I assume it is declared later in the XAML. If I move my InputBindings to the end of the XAML file everything works as intended.
I kinda prefer my InputBindings to be at the top, is it possible to make it ignore the declaration order?
#Stewbob What are you talking about?
Take a look at this: http://msdn.microsoft.com/en-us/library/ms752308.aspx
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Open"
Executed="OpenCmdExecuted"
CanExecute="OpenCmdCanExecute"/>
</Window.CommandBindings>
According to what you said this should never work properly but it does:
<StackPanel>
<Menu>
<MenuItem Command="ApplicationCommands.Paste"
CommandTarget="{Binding ElementName=mainTextBox}" />
</Menu>
<TextBox Name="mainTextBox"/>
</StackPanel>
From what you said the binding comes first also it will be executed first and therefore the binding to mainTextBox should never work. Thats very not true.
Sure you can do everything in XAML, including such Binding at Window level. Show more code of your XAML/MyViewElement. Maybe we could tell you how to do it without errors. Also post your error here please.
But, this fails because MyViewElement is not found because I assume it is declared later in the XAML.
To avoid that, you can use the following in the code behind instead of the constructor:
protected override void OnInitialized(EventArgs e)
{
SomeCommand = new DelegateCommand(SomeExecuteMethod);
InitializeComponent();
base.OnInitialized(e);
}
This ensures the commands are already instantiated before you use them with:
Command="{Binding ElementName=MyUserCOntrol, Path=SomeCommand}"

Is there any way to alias commands in WPF?

Is there any way to effectively "alias" commands in WPF ? My situation is this : I've created an application that uses ApplicationCommands.Delete in the context of a graphical editor that has a number of customized canvases. Some of the controls that are on these canvases use TextBoxes, but here's the problem : TextBox doesn't respond to ApplicationCommands.Delete, it responds to EditorCommands.Delete. Is there any way to cleanly get TextBox to respond to ApplicationCommands.Delete without subclassing or manually setting bindings on every TextBox instance ?
To answer your specific question, I know of no way to cause two separate routed commands to be treated as the same command. But because ApplicationCommands.Delete is a routed command, after it is delivered to its target, the TextBox and there is no command binding, it will begin bubbling up. So the simplest solution that meets your requirements is to install a command binding for ApplicationCommands.Delete somewhere inbetween the TextBox all the way up to and possibly including the Window, that implements the behavior you desire.
Here's an example that installs a handler on a parent Grid that sends the "right" command the the focused element which in this case will be a TextBox:
<Grid>
<Grid.CommandBindings>
<CommandBinding Command="ApplicationCommands.Delete" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
</Grid.CommandBindings>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Header="_Edit">
<MenuItem Header="_Delete" Command="ApplicationCommands.Delete"/>
</MenuItem>
</Menu>
<StackPanel>
<TextBox Text="Some text"/>
</StackPanel>
</DockPanel>
</Grid>
and here's the code-behind:
private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
EditingCommands.Delete.Execute(null, Keyboard.FocusedElement);
}

WPF custom command in context menu are disabled until any button clicked

I have a custom command and I try to execute them from the context menu, but they are always displayed as disabled unless I click any button on the UI (buttons do not have anything to do with commands).
After clicking a button, commands start to be displayed correctly (when they are unavailable they get disabled and enabled if available).
Edit: it turns out that it is not the button click which makes command work correctly, but button or other controls in focus (e.g. if I tab into a control this also enables my commands).
Here is the code for commands:
<Window.InputBindings>
<KeyBinding Command="{x:Static local:MainWindow.Quit}" Key="Q" Modifiers="Ctrl"/>
<KeyBinding Command="{x:Static local:MainWindow.Disconnect}" Key="D" Modifiers="Ctrl"/>
</Window.InputBindings>
<Window.ContextMenu>
<ContextMenu Opacity="95">
<MenuItem Header="Quit Application Ctrl + Q" Command="{x:Static local:MainWindow.Quit}"/>
<MenuItem Header="Disconnect from the pump Ctrl + D" Command="{x:Static local:MainWindow.Disconnect}"/>
</ContextMenu>
</Window.ContextMenu>
Here is the commands CanExecuteMethod:
public static RoutedCommand Quit = new RoutedCommand();
private void QuitCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
e.Handled = true;
}
This issue is due to the ContextMenu being on a separate Visual and Logical Tree to that of the Window and its Controls.
For anyone still looking for an answer to this issue - After trawling the internet I have found the most effective answer to be to include the following in any declaration of a MenuItem that needs its commands to be heard by it's "owner".
In layman's terms; if you want the commands of your context menu to be heard by the thing you're right clicking on. Add this code:
CommandTarget="{Binding Path=PlacementTarget,
RelativeSource={RelativeSource AncestorType=ContextMenu}
}"
Example:
<ContextMenu>
<MenuItem Header="Close" Command="Application.Close"
CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
</ContextMenu>
This will also work within Templates (something I found a lot of another solutions not to support). Here is an explanation of the meaning of the statement taken from elsewhere (I'm appalling at explaining things):
Every FrameworkElement has a DataContext that is an arbitrary object. The default source for a data binding is that DataContext. You can use RelativeSource.Self to change the source for a binding to the FrameworkElement itself instead of its DataContext. So the RelativeSource part just moves you "up one level" from the DataContext of the FrameworkElement to the FrameworkElement itself. Once you are at the FrameworkElement you can specify a path to any of its properties. If the FrameworkElement is a Popup, it will have a PlacementTarget property that is the other FrameworkElement that the Popup is positioned relative to.
In short, if you have a Popup placed relative to a TextBox for example, that expression sets the DataContext of the Popup to the TextBox and as a result {Binding Text} somewhere in the body of the Popup would bind to the text of the TextBox.
I honestly hope that this information saves someone who's new to WPF the headache I've gone through this weekend... though it did teach me a lot!
Completely different track, now:
there is indeed something special about the ContextMenu as the carrier for commands:
the menu is not regarded as part of the window and therefore does not behave like an element in its visual tree would.
There are different solutions for your problems defined here:
http://www.wpftutorial.net/RoutedCommandsInContextMenu.html
The easiest approach seems to be adding this to your XAML (for the window):
FocusManager.FocusedElement="{Binding RelativeSource={x:Static RelativeSource.Self}, Mode=OneTime}"
I just ran into this while trying to implement a custom context menu for AvalonDock. None of the solutions suggested above worked for me.
I got the context menu working by explicitly registering my command handlers on the ContextMenu class in addition to the main widow. The function below is a helper I used for command registration.
void RegisterCmd(RoutedCommand command, ExecutedRoutedEventHandler handler, CanExecuteRoutedEventHandler canExecute)
{
var binding = new CommandBinding(command, handler, canExecute);
this.CommandBindings.Add(binding);
CommandManager.RegisterClassCommandBinding(typeof(ContextMenu), binding);
}
There is probably some change "behind the scenes" that would normally enable the commands, but the view is not aware of this change.
One would need to see the Command-implementations to give more precise hints.
You can either make anything that changes your command-enable-state notify the view or manually trigger a command-refresh via CommandManager.InvalidateRequerySuggested(), for example when the context-menu opens.
WPF ICommands work that way; they requery their CanExecute function whenever something in the view changes (e.g. PropertyChanged-event is fired or a button is clicked), but they don't requery if they have no reason to.
This is a known bug. If there is no focused element in the window's main focus scope, the CanExecute routing will stop at the ContextMenu, so it will not reach to the CommandBinding on the Window, one workaround is to bind MenuItem's CommandTarget to the main window, as following code demonstrates:
<Window.ContextMenu>
<ContextMenu >
<ContextMenu.Items>
<MenuItem Command="ApplicationCommands.Open"
CommandTarget="{Binding Path=PlacementTarget,RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}}"/>
</ContextMenu.Items>
</ContextMenu>
</Window.ContextMenu>

Resources