Reputation: 23833
I have an existing WPF application in which I have a fairly advanced command system. I am now developing a WinForms application in which I want to adopt a similar command system. This is going well but I am struggling with shortcuts and the key binding translation.
For the WPF case, I bind key gestures for commands to user interface elements via the following method
public void BindKeyGestures(UIElement uiElement)
{
foreach (var keyboardShortcut in _keyboardShortcuts)
{
if (keyboardShortcut.KeyGesture != null)
{
uiElement.InputBindings.Add(new InputBinding(
_commandService.GetTargetableCommand(_commandService.GetCommand(keyboardShortcut.CommandDefinition)),
keyboardShortcut.KeyGesture));
}
}
}
Is there a way to add InputBindings
for a WinForms Control
(I believe this is unlikely as it is a WPF construct), and if there isn't, how can I add the shortcut without having to explicitly override ProcessCmdKey
of the containing form?
Upvotes: 0
Views: 361
Reputation: 5019
There are a few specific controls (toolstrip items, menu items) which have a ShortcutKeys property that you can use (for example: https://msdn.microsoft.com/en-us/library/system.windows.forms.toolstripmenuitem.shortcutkeys(v=vs.110).aspx).
For other controls, there's nothing built in that I know of, and you'll need to create some system yourself. Here's a simple extension method that you can use:
public static void Bind(this Control control, Keys shortcut, Action action)
{
Form form = control.FindForm();
if (form == null) throw new NullReferenceException($"Form not found for control: {control.Text ?? control.ToString()}");
form.KeyPreview = true;
form.KeyDown += (sender, args) =>
{
if (args.KeyData == shortcut) action();
};
}
This needs to be called after the control is assigned to a form, otherwise it would throw an exception. Also this does not cover unsubscribing the KeyDown event, which will be less trivial to implement (something along the lines of caching the control+shortcut+delegate triplets, and then unsubscribing when calling Unbind).
The above code can be used like this:
Button button = new Button { Text = "Click Me!" };
form.Controls.Add(button);
....
button.Bind(Keys.F | Keys.Control, () => doSomething()); //Will do something on Ctrl+F
Upvotes: 1