I'm handling key bindings in our application by allowing the key binding events to bubble up to the main window view where keybindings are defined in xaml and handled in the main window view model, e.g.,
<Window.InputBindings>
<KeyBinding Key="Left" Modifiers="Alt" Command="{Binding NavigateBackCommand}"/>
<KeyBinding Key="Right" Modifiers="Alt" Command="{Binding NavigateForwardCommand}"/>
<KeyBinding Key="c" Modifiers="Control" Command="{Binding CopyCommand}"/>
<KeyBinding Key="v" Modifiers="Control" Command="{Binding PasteCommand}"/>
<KeyBinding Key="d" Modifiers="Control" Command="{Binding DuplicateCommand}"/>
<KeyBinding Key="n" Modifiers="Control" Command="{Binding AddCommand}"/>
<KeyBinding Key="i" Modifiers="Control" Command="{Binding ImportCommand}"/>
<KeyBinding Key="e" Modifiers="Control" Command="{Binding ExportCommand}"/>
<KeyBinding Key="a" Modifiers="Control" Command="{Binding SelectAllCommand}"/>
<KeyBinding Key="k" Modifiers="Control" Command="{Binding DeselectCommand}"/>
<KeyBinding Key="z" Modifiers="Control" Command="{Binding UndoCommand}"/>
<KeyBinding Key="y" Modifiers="Control" Command="{Binding RedoCommand}"/>
<KeyBinding Key="z" Modifiers="Control+Shift" Command="{Binding RedoCommand}"/>
<KeyBinding Key="F5" Command="{Binding RefreshCommand}"/>
<KeyBinding Key="Delete" Command="{Binding DeleteCommand}"/>
<KeyBinding Key="Escape" Command="{Binding EscapeCommand}"/>
</Window.InputBindings>
This works well except for the TextBox
control where the undo event ("Ctrl+Z") never appears to bubble up to the main window. I have set IsUndoEnabled
on the TextBox
to false, but it still doesn't appear to bubble. It's almost as if the TextBox
is handling the event thereby preventing it bubbling all the way up.
I have spiked a fix using the below in a custom TextBox
(MyTextBox
), i.e., listen for the CommandBinding
in the control and when hit look for the KeyBinding
in the window and execute the associated command
public MyTextBox()
{
IsUndoEnabled = false;
CommandBindings.Add(new CommandBinding(
ApplicationCommands.Undo,
((sender, args) =>
{
var window = Window.GetWindow(this);
foreach (var keyBinding in window.InputBindings.OfType<KeyBinding>())
{
if (keyBinding.Key == Key.Y && keyBinding.Modifiers == ModifierKeys.Control)
{
keyBinding.Command.Execute(null);
}
}
})));
}
but this seems very hacky. Is there away to disable a TextBox
's built-in undo command and rather allow the key binding to bubble up so I can handle it?