How to handle keyboard shortcuts and events correctly?

There was a problem with short cuts, any help / advice would be greatly appreciated! Purpose: I need to be able to handle short keys, with and without modifiers, in my application. So, for example, I need to process the key "a", as well as "CTR + a". But I want to process them only if these keys are not managed. For example, the TextBox class accepts most keys, including some commands, such as "Ctrl + C", etc., so I don’t want to intercept these events when the TextBox will process them.

I tried using commands, as well as attaching events to KeyUp on the window, but the commands intercept the keys before the TextBox can see them, KeyDown bubbles to the Window level, even if the TextBox used the key! How can I get my window to get keys that are NOT handled by any child control? Please see the code below which does not work for me. In addition, since I have many different controls, I have the β€œright” solution: I rather do not attach handlers to every instance of the control in my window.

<Window x:Class="KeyTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Window.CommandBindings> <CommandBinding Command="Help" CanExecute="HelpCanExecute" Executed="HelpExecuted" /> </Window.CommandBindings> <Window.InputBindings> <KeyBinding Command="Help" Key="H" /> </Window.InputBindings> <Grid> <WrapPanel> <TextBox Name="myLOG" Width="300" Height="200" Background="LightBlue" /> <TextBox Name="myINPUT" Width="300" Height="200" /> <Button Content="JUST FOR FUN" /> </WrapPanel> </Grid> 

And for C #

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace KeyTest { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private void HelpCanExecute(object sender, CanExecuteRoutedEventArgs e) { myLOG.Text += "HELP CAN EXECUTE\n"; e.CanExecute = true; e.Handled = true; } private void HelpExecuted(object sender, ExecutedRoutedEventArgs e) { myLOG.Text += "HELP EXECUTED!!!\n"; e.Handled = true; } public void myKeyUpHandler(Object sender, KeyEventArgs args) { myLOG.Text += "KEY UP EVENT! " + args.Key + "\n"; } public MainWindow() { InitializeComponent(); this.KeyUp += new KeyEventHandler(myKeyUpHandler); } } } 

When the focus is in the text field, pressing "h" invokes the command, although I want "h" to go only to the text field. In addition, if inside the text field pressing any alphanumeric key fires the KeyUp event, although, as I understand it, the text field should handle = true this event!

Thanks for the help!

+4
source share
2 answers

You need to research using the types of preview events. They occur before other controls will handle events. Then you want to stop the event bubbles. I believe that you are doing it right with e.Handled.

Explore this: http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.previewkeydown.aspx

Not sure how to do this in xaml for what you want to do. Expression mixing libraries can be very useful for dropping event commands. See here: http://jacokarsten.wordpress.com/2009/03/27/applying-command-binding-to-any-control-and-any-event/

+2
source

Dude I think you need to use the previewKeyDown or PreviewKeyUp event instead of the keyup event here, because the PreviewKeydown and PreviewKeyup Event create a tunneling effect (OPPOSITE is the bubbling effect, where the events that were fired from the RootParent control that fired the event down for the control that originally called event (also known as the source)). You can use this tunneling effect to handle events, as well as use events that are triggered through the bubbling effect. Another thing is that the PreviewKeyDown and PrevieKeyup events that were fired before the key change events occur. This can allow you to intercept the event in the cleanest way.

Another thing, I think, you need to check the source of the event so that you can select the controls that could trigger these events.

Here is a sample code

  public void nameOfCotrol_PreviewKeyDown(object sender, RoutedEventArgs e) { if((e.OriginalSource as Control).Name == "NameOfControls That would be allowed to fire the event") { You're stuff to be done here } else { e.handled = true; } } 

Hope this can help in a small manner. Thanks

+1
source

Source: https://habr.com/ru/post/1386622/


All Articles