Is it possible to dynamically define KeyBindings based on a bound data source? I have a screen with a grid and I allow users to save various layouts for it. I currently bind the grids context menu to the layout names (via the ViewModel), allowing them to switch layouts via the menu.
However, I would like to associate each layout with a shortcut key. As the shortcut keys are defined by the user I can't simply add a number of <KeyBinding>
elements in the window XAML. Another issue is the binding would need to supply the name of the layout as a command parameter.
Is there any way to dynamically create a series of <KeyBinding>
elements from a dynamic source?
As a test I have added the bindings statically to my view XAML and they work fine, but this was only to test my concept:
<UserControl.InputBindings>
<KeyBinding Key="F7" Command="{Binding MyCommand}" CommandParameter="My Layout Name"/>
<KeyBinding Key="F8" Command="{Binding MyCommand}" CommandParameter="My Other Layout Name"/>
</UserControl.InputBindings>
Here's code I use to create key bindings dynamically as part of a snippet editor that allows snippets to be executed on a hotkey.
In addition to earlier examples it also demonstrates how to parse user input of key combos:
// example key combo from user input
var ksc = "Alt+Shift+M";
ksc = ksc.ToLower();
KeyBinding kb = new KeyBinding();
if (ksc.Contains("alt"))
kb.Modifiers = ModifierKeys.Alt;
if (ksc.Contains("shift"))
kb.Modifiers |= ModifierKeys.Shift;
if (ksc.Contains("ctrl") || ksc.Contains("ctl"))
kb.Modifiers |= ModifierKeys.Control;
string key =
ksc.Replace("+", "")
.Replace("-", "")
.Replace("_", "")
.Replace(" ", "")
.Replace("alt", "")
.Replace("shift", "")
.Replace("ctrl", "")
.Replace("ctl", "");
key = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(key);
if (!string.IsNullOrEmpty(key))
{
KeyConverter k = new KeyConverter();
kb.Key = (Key)k.ConvertFromString(key);
}
// Whatever command you need to bind to
// CommandBase here is a custom class I use to create commands
// with Execute/CanExecute handlers
kb.Command = new CommandBase((s, e) => InsertSnippet(snippet),
(s,e) => Model.IsEditorActive);
Model.Window.InputBindings.Add(kb);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With