Reputation: 55
Hi I am having trouble with WPF creating a RoutedUICommand that works similar to an ApplicationCommand. Ideally I want to have a single 'Duplicate' MenuItem that works with two different UserControls. Whether or not the MenuItem is active will depend on which UserControl is selected and if the UserControl contains a selected object (the same way cut, copy and past work on different textboxes, etc).
As per this StackOverflow, question I have created the static class below:
namespace App.Classes
{
public static class myCommands
{
private static readonly RoutedUICommand _duplicateCmd = new RoutedUICommand("Duplicate", "Duplicate", typeof(myCommands));
public static RoutedUICommand Duplicate
{
get { return _duplicateCmd; }
}
}
}
In the main Window's XAML file I have added a reference to the class's namespace and a KeyBinding to the command.
<Window x:Class="GUI.App.Views.Windows.wndMain"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:classes="clr-namespace:App.Classes">
<Window.InputBindings>
<KeyBinding Key="D" Modifiers="Control" Command="{Binding classes:myCommands.Duplicate}" />
</Window.InputBindings>
In the MenuItem I have added a Command binding to the 'Duplicate' command
<MenuItem Name="mnCopy" Header="Copy" Command="ApplicationCommands.Copy" InputGestureText="Ctrl+C" />
<MenuItem Name="mnDuplicate" Header="Duplicate" Command="{Binding classes:myCommands.Duplicate}" InputGestureText="Ctrl+D"/>
And finally in each of my UserControls I have added CommandBindings to the 'Duplicate' and other ApplicationCommands.
<UserControl.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" Executed="CommandBinding_Copy" CanExecute="CommandBindingCanExecute_Copy" />
<CommandBinding Command="classes:myCommands.Duplicate" Executed="CommandBinding_DuplicateControls" CanExecute="CommandBindingCanExecute_DuplicateControls" />
</UserControl.CommandBindings>
The code-behind for my Executed and CanExecute for each of the UserControls is
/// <summary>
///
/// </summary>
public void CommandBinding_Copy(Object sender, ExecutedRoutedEventArgs e)
{
_viewModel.Copy();
}
/// <summary>
///
/// </summary>
public void CommandBinding_Duplicate(Object sender, ExecutedRoutedEventArgs e)
{
_viewModel.Duplicate();
}
/// <summary>
///
/// </summary>
public void CommandBindingCanExecute_Copy(Object sender, CanExecuteRoutedEventArgs e)
{
_viewModel.CanExecute_Copy();
}
/// <summary>
///
/// </summary>
public void CommandBindingCanExecute_Duplicate(Object sender, CanExecuteRoutedEventArgs e)
{
_viewModel.CanExecute_Duplicate();
}
This works perfectly for my ApplicationCommands and the appropriate Executed and CanExecute get called depending upon which UserControl is selected. But I can't get it to work with my 'Duplicate' RoutedUICommand. Does anybody know what I'm doing wrong or am missing? Will be grateful for any help anyone can give.
Upvotes: 1
Views: 1181
Reputation: 33364
You're binding to a static property via Path
and that won't work. Change Binding
to x:Static
and should work
<MenuItem Name="mnCopy" Command="ApplicationCommands.Copy" />
<MenuItem Name="mnDuplicate" Command="{x:Static classes:myCommands.Duplicate}"/>
On a side note RoutedUICommand
has overloaded constructor that accepts InputGestureCollection
where you can bind Ctrl+D when you command is created.
private static readonly RoutedUICommand _duplicateCmd =
new RoutedUICommand(
"Duplicate",
"Duplicate",
typeof(myCommands),
new InputGestureCollection(new InputGesture[] { new KeyGesture(Key.D, ModifierKeys.Control) }));
advantage is that you won't have to specify InputGestureText
, as you don't have to ApplicationCommands.Copy
, and because you use RoutedUICommand
you also don't need to specify Header
. If you do that both InputGestureText
and Header
will be taken by default from your RoutedUICommand
and all you actually need to specify against MenuItem
is a Command
Upvotes: 2