I know about using _
instead of &
, but I\'m looking at all the Ctrl + type shortcuts.
Ctrl+Z for undo, Ctrl+S for save, etc.
Is there a \'standard\' way for implementing these in WPF applications? Or is it a case of roll your own and wire them up to whatever command/control?
I understand the standard way is by creating commands and then adding your shortcut keys to them as InputGestures.
This enables the shortcut keys to work even if they\'re not hooked up to any controls. And since menu items understand keyboard gestures, they\'ll automatically display your shortcut key in the menu items text, if you hook that command up to your menu item.
Create static attribute to hold a command (preferably as a property in a static class you create for commands - but for a simple example, just using a static attribute in window.cs):
public static RoutedCommand MyCommand = new RoutedCommand();
Add the shortcut key(s) that should invoke method:
MyCommand.InputGestures.Add(new KeyGesture(Key.S, ModifierKeys.Control));
Create a command binding that points to your method to call on execute. Put these in the command bindings for the UI element under which it should work for (e.g., the window) and the method:
<Window.CommandBindings>
<CommandBinding Command=\"{x:Static local:MyWindow.MyCommand}\" Executed=\"MyCommandExecuted\"/>
</Window.CommandBindings>
private void MyCommandExecuted(object sender, ExecutedRoutedEventArgs e) { ... }
I found this to be exactly what I was looking for related to key binding in WPF:
<Window.InputBindings>
<KeyBinding Modifiers=\"Control\"
Key=\"N\"
Command=\"{Binding CreateCustomerCommand}\" />
</Window.InputBindings>
See blog post MVVM CommandReference and KeyBinding
Try this code...
First create a RoutedComand object
RoutedCommand newCmd = new RoutedCommand();
newCmd.InputGestures.Add(new KeyGesture(Key.N, ModifierKeys.Control));
CommandBindings.Add(new CommandBinding(newCmd, btnNew_Click));
It depends on where you want to use those.
TextBoxBase
-derived controls already implement those shortcuts. If you want to use custom keyboard shortcuts you should take a look on Commands and Input gestures. Here is a small tutorial from Switch on the Code: WPF Tutorial - Command Bindings and Custom Commands
Documenting this answer for others, as there is a much simpler way to do this that is rarely referenced, and doesn\'t require touching the XAML at all.
To link a keyboard shortcut, in the Window constructor simply add a new KeyBinding to the InputBindings collection. As the command, pass in your arbitrary command class that implements ICommand. For the execute method, simply implement whatever logic you need. In my example below, my WindowCommand class takes a delegate that it will execute whenever invoked. When I construct the new WindowCommand to pass in with my binding, I simply indicate in my initializer, the method that I want the WindowCommand to execute.
You can use this pattern to come up with your own quick keyboard shortcuts.
public YourWindow() //inside any WPF Window constructor
{
...
//add this one statement to bind a new keyboard command shortcut
InputBindings.Add(new KeyBinding( //add a new key-binding, and pass in your command object instance which contains the Execute method which WPF will execute
new WindowCommand(this)
{
ExecuteDelegate = TogglePause //REPLACE TogglePause with your method delegate
}, new KeyGesture(Key.P, ModifierKeys.Control)));
...
}
Create a simple WindowCommand class which takes an execution delegate to fire off any method set on it.
public class WindowCommand : ICommand
{
private MainWindow _window;
//Set this delegate when you initialize a new object. This is the method the command will execute. You can also change this delegate type if you need to.
public Action ExecuteDelegate { get; set; }
//You don\'t have to add a parameter that takes a constructor. I\'ve just added one in case I need access to the window directly.
public WindowCommand(MainWindow window)
{
_window = window;
}
//always called before executing the command, mine just always returns true
public bool CanExecute(object parameter)
{
return true; //mine always returns true, yours can use a new CanExecute delegate, or add custom logic to this method instead.
}
public event EventHandler CanExecuteChanged; //i\'m not using this, but it\'s required by the interface
//the important method that executes the actual command logic
public void Execute(object parameter)
{
if (ExecuteDelegate != null)
{
ExecuteDelegate();
}
else
{
throw new InvalidOperationException();
}
}
}
I had a similar problem and found @aliwa\'s answer to be the most helpful and most elegant solution; however, I needed a specific key combination, Ctrl + 1. Unfortunately I got the following error:
\'1\' cannot be used as a value for \'Key\'. Numbers are not valid enumeration values.
With a bit of further search, I modified @aliwa\'s answer to the following:
<Window.InputBindings>
<KeyBinding Gesture=\"Ctrl+1\" Command=\"{Binding MyCommand}\"/>
</Window.InputBindings>
I found this to work great for pretty well any combination I needed.
VB.NET:
Public Shared SaveCommand_AltS As New RoutedCommand
Inside the loaded event:
SaveCommand_AltS.InputGestures.Add(New KeyGesture(Key.S, ModifierKeys.Control))
Me.CommandBindings.Add(New CommandBinding(SaveCommand_AltS, AddressOf Me.save))
No XAML is needed.
How to associate the command with a MenuItem
:
<MenuItem Header=\"My command\" Command=\"{x:Static local:MyWindow.MyCommand}\"/>