I have an application that contains Menu and sub menus. I have attached Appliocation Commands to some of the sub menu items such as Cut, Copy and Paste.
I also have some other menu items that do not have application commands.
How could I add a custom command binding to those sub menu items?
I have gone through this article but unable to attach event to my sub menu items.
I use a static class that I place after the Window1 class (or whatever the window class happens to be named) where I create instances of the RoutedUICommand class:
public static class Command {
public static readonly RoutedUICommand DoSomething = new RoutedUICommand("Do something", "DoSomething", typeof(Window1));
public static readonly RoutedUICommand SomeOtherAction = new RoutedUICommand("Some other action", "SomeOtherAction", typeof(Window1));
public static readonly RoutedUICommand MoreDeeds = new RoutedUICommand("More deeds", "MoreDeeeds", typeof(Window1));
}
Add a namespace in the window markup, using the namespace that the Window1 class is in:
xmlns:w="clr-namespace:NameSpaceOfTheApplication"
Now I can create bindings for the commands just as for the application commands:
<Window.CommandBindings>
<CommandBinding Command="ApplicationCommands.Open" Executed="CommandBinding_Open" />
<CommandBinding Command="ApplicationCommands.Paste" Executed="CommandBinding_Paste" />
<CommandBinding Command="w:Command.DoSomething" Executed="CommandBinding_DoSomething" />
<CommandBinding Command="w:Command.SomeOtherAction" Executed="CommandBinding_SomeOtherAction" />
<CommandBinding Command="w:Command.MoreDeeds" Executed="CommandBinding_MoreDeeds" />
</Window.CommandBindings>
And use the bindings in a menu for example:
<MenuItem Name="Menu_DoSomething" Header="Do Something" Command="w:Command.DoSomething" />
Command.DoSomething
) have to be public, otherwise you will receive the following exception "CommandConverter cannot convert from System.String". I'm assuming this is because the code that is managing commands is probably in a different assembly, and as a result can't see the internal
property. I just started learning WPF last week :D –
Lightless Command
class did you mean typeof(Command)
instead of typeof(Window1)
–
Untuck Instead of defining them in a static class, you might as well declare the commands directly in XAML. Example (adapted from Guffas nice example):
<Window.Resources>
<RoutedUICommand x:Key="DoSomethingCommand" Text="Do Something" />
<RoutedUICommand x:Key="DoSomethingElseCommand" Text="Do Something Else" />
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource DoSomethingCommand}" Executed="CommandBinding_DoSomething" />
<CommandBinding Command="{StaticResource DoSomethingElseCommand}" Executed="CommandBinding_DoSomethingElse" />
</Window.CommandBindings>
...
<MenuItem Name="Menu_DoSomething" Header="Do Something" Command="{StaticResource DoSomethingCommand}" />
CommandBinding_DoSomething
and CommandBinding_DoSomethingElse
are C# code. 3./4. For a general discussion about the advantages of RoutedCommands vs. regular Button_Click-bindings, see, for example, joshsmithonwpf.wordpress.com/2008/03/18/… (Section "Who Cares?"). –
Jeffers I Know that my answer is too late, but i hope it will help for the future.
I Like Guffa and Heinzi answers, but you can use only one command to achieve the previous result. I usually use the Help command
<Window.CommandBindings>
<CommandBinding Command="{StaticResource Help}" Executed="HelpExecuted" />
</Window.CommandBindings>
and I use CommandParametr with each call e.g
<Window.InputBindings>
<KeyBinding Command="{StaticResource Help}" Key="A" Modifiers="Ctrl" CommandParameter="Case1"/>
<KeyBinding Command="{StaticResource Help}" Key="B" Modifiers="Ctrl" CommandParameter="Case2"/>
<KeyBinding Command="{StaticResource Help}" Key="C" Modifiers="Ctrl" CommandParameter="Case3"/>
<KeyBinding Command="{StaticResource Help}" Key="D" Modifiers="Ctrl" CommandParameter="Case4"/>
<MouseBinding Command="{StaticResource Help}" MouseAction="LeftDoubleClick" CommandParameter="Case5" />
</Window.InputBindings>
or
<Button Command="Help" CommandParameter="Case6" Content="Button">
<Button.InputBindings>
<KeyBinding Command="{StaticResource Help}" Gesture="Ctrl+D" CommandParameter="Case7"/>
</Button.InputBindings>
</Button>
and in the cs file
private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
{
string str = e.Parameter as string;
switch (str)
{
case null://F1 Pressed default Help
//Code
break;
case "Case1":
//Code
break;
case "Case2":
//Code
break;
case "Case3":
//Code
break;
case "Case4":
break;
case "Case5":
//Code
break;
case "Case6":
//Code
break;
case "Case7":
//Code
break;
}
e.Handled = true;
}
and if you are using MVVM pattern
private void HelpExecuted(object sender, ExecutedRoutedEventArgs e)
{
string str = e.Parameter as string;
Mvvm_Variable.Action(Input: str);
e.Handled = true;
}
and move the switch to ViewModule site. and Action is a method in the same ViewModule class.
RoutedUICommand
in their answers. This class has a Text
property, from which text is taken to automatically populate menu entries which invoke that command (and can be used elsewhere - I bind button text to it quite often through a shared template). If you use one command (say, "Help"), all the menu items will have the same single piece of text defined in Help.Text
. Depending on your preferred architecture, this may not be a big problem, but I think it's something to be aware of. –
Detriment © 2022 - 2024 — McMap. All rights reserved.