I'm using the common RelayCommand class. Far up the visual tree, I have a number of my commands tied to UserControl.InputBindings with some common letter shortcuts. I also have a TextBox. However, when my TextBox has focus and I press any of the keys that are bound to commands, the command executes and the character never shows in the TextBox. I had thought that the focused element would have the first chance to use the key and mark it as handled. Why does my command get triggered first? I want it triggered only when no other input controls further down the tree handle the event.
Update: the critical piece of code seems to be at the bottom of CommandManager.TranslateInput. Disassembled here:
bool continueRouting = false;
RoutedCommand routedCommand = command as RoutedCommand;
if (routedCommand != null)
{
if (routedCommand.CriticalCanExecute(parameter, target, inputEventArgs.UserInitiated, out continueRouting))
{
continueRouting = false;
CommandManager.ExecuteCommand(routedCommand, parameter, target, inputEventArgs);
}
}
else if (command.CanExecute(parameter))
command.Execute(parameter);
inputEventArgs.Handled = !continueRouting;
There is no way to use an ICommand and have the Handled not return true. My only option is to make the TextBox handle the key input before it goes to the UIElement.OnKeyDownThunk, which calls right into the CommandManager. Or is there any other way to trigger a RelayCommand aside from the InputBinding? Here is the stack trace:
> Asi.ViewModelShared.dll!Asi.ViewModelShared.RelayCommand.Execute(object parameter) Line 50 C#
PresentationCore.dll!System.Windows.Input.CommandManager.TranslateInput(System.Windows.IInputElement targetElement, System.Windows.Input.InputEventArgs inputEventArgs) + 0x5c5 bytes
PresentationCore.dll!System.Windows.UIElement.OnKeyDownThunk(object sender, System.Windows.Input.KeyEventArgs e) + 0x52 bytes
PresentationCore.dll!System.Windows.Input.KeyEventArgs.InvokeEventHandler(System.Delegate genericHandler, object genericTarget) + 0x2c bytes
PresentationCore.dll!System.Windows.RoutedEventArgs.InvokeHandler(System.Delegate handler, object target) + 0x33 bytes
PresentationCore.dll!System.Windows.RoutedEventHandlerInfo.InvokeHandler(object target, System.Windows.RoutedEventArgs routedEventArgs) + 0x44 bytes
PresentationCore.dll!System.Windows.EventRoute.InvokeHandlersImpl(object source, System.Windows.RoutedEventArgs args, bool reRaised) + 0x1a8 bytes
PresentationCore.dll!System.Windows.UIElement.RaiseEventImpl(System.Windows.DependencyObject sender, System.Windows.RoutedEventArgs args) + 0x73 bytes
PresentationCore.dll!System.Windows.UIElement.RaiseTrustedEvent(System.Windows.RoutedEventArgs args) + 0x3d bytes
PresentationCore.dll!System.Windows.UIElement.RaiseEvent(System.Windows.RoutedEventArgs args, bool trusted) + 0x40 bytes
PresentationCore.dll!System.Windows.Input.InputManager.ProcessStagingArea() + 0x1f8 bytes
PresentationCore.dll!System.Windows.Input.InputManager.ProcessInput(System.Windows.Input.InputEventArgs input) + 0x45 bytes
PresentationCore.dll!System.Windows.Input.InputProviderSite.ReportInput(System.Windows.Input.InputReport inputReport) + 0x62 bytes
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(System.IntPtr hwnd, System.Windows.Input.InputMode mode, int timestamp, System.Windows.Input.RawKeyboardActions actions, int scanCode, bool isExtendedKey, bool isSystemKey, int virtualKey) + 0xee bytes
PresentationCore.dll!System.Windows.Interop.HwndKeyboardInputProvider.ProcessKeyAction(ref System.Windows.Interop.MSG msg, ref bool handled) + 0xac bytes
PresentationCore.dll!System.Windows.Interop.HwndSource.CriticalTranslateAccelerator(ref System.Windows.Interop.MSG msg, System.Windows.Input.ModifierKeys modifiers) + 0x94 bytes
PresentationCore.dll!System.Windows.Interop.HwndSource.OnPreprocessMessage(object param) + 0x12c bytes