I am currently programming an application consisting of the main window (DataContext here is a class of mine, MainWindowController) where I have defined this KeyBinding:
<Window.InputBindings>
<KeyBinding Key="N" Modifiers="Control" Command="{Binding Path=NewProgramCommand}"/>
<KeyBinding Key="O" Modifiers="Control" Command="{Binding Path=OpenProgramCommand}"/>
<KeyBinding Key="S" Modifiers="Control" Command="{Binding Path=SaveProxyCommand}"/>
<KeyBinding Key="W" Modifiers="Control" Command="{Binding Path=CloseProxyCommand}"/>
</Window.InputBindings>
I can open other windows from my main window. I have defined an abstract class, AbstractWindow: Window, to handle, amongst other things, the application closing. My other window is created as AbstractWindows
<window:AbstractWindow x:Class="FinancialViewModule.FinancialView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Height="800" Width="1280"
d:DesignHeight="300" d:DesignWidth="300">
When the user clicks on a button, a command creates the new window.
mController.FinancialView = new FinancialView();
mController.FinancialView.Show();
I want my KeyBindings to work from all the windows so, in the AbstractWindow constructor, I have:
InputBindings.AddRange(Application.Current.MainWindow.InputBindings);
The shortcuts work from the FinancialView window but I have an error in the Output :
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=NewProgramCommand; DataItem='MainWindowController' (HashCode=37314933); target element is 'KeyBinding' (HashCode=38008833); target property is 'Command' (type 'ICommand')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=OpenProgramCommand; DataItem='MainWindowController' (HashCode=37314933); target element is 'KeyBinding' (HashCode=5210297); target property is 'Command' (type 'ICommand')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=SaveProxyCommand; DataItem='MainWindowController' (HashCode=37314933); target element is 'KeyBinding' (HashCode=34357331); target property is 'Command' (type 'ICommand')
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=CloseProxyCommand; DataItem='MainWindowController' (HashCode=37314933); target element is 'KeyBinding' (HashCode=41051448); target property is 'Command' (type 'ICommand')
What can I do to avoid this error? Is there a better way to have the same shortcuts from all the windows of an app?
Create new key bindings in each window instance:
KeyBinding n = new KeyBinding() { Modifiers = ModifierKeys.Control, Key = Key.N };
KeyBinding o = new KeyBinding() { Modifiers = ModifierKeys.Control, Key = Key.O };
KeyBinding s = new KeyBinding() { Modifiers = ModifierKeys.Control, Key = Key.S };
KeyBinding w = new KeyBinding() { Modifiers = ModifierKeys.Control, Key = Key.W };
BindingOperations.SetBinding(n, InputBinding.CommandProperty, new Binding("NewProgramCommand"));
BindingOperations.SetBinding(o, InputBinding.CommandProperty, new Binding("OpenProgramCommand"));
BindingOperations.SetBinding(s, InputBinding.CommandProperty, new Binding("SaveProxyCommand"));
BindingOperations.SetBinding(w, InputBinding.CommandProperty, new Binding("CloseProxyCommand"));
InputBindings.AddRange(new KeyBinding[4] { n, o, s, w });
...and make sure that you set each window's DataContext
to a MainWindowController
or whatever type in which your commands are defined.