How to get modifier keys correctly in WPF KeyDown event?

I saw several answers suggesting using Keyboard.Modifiers to determine if the KeyDown for a key that had a set of modifiers. Unfortunately, since Keyboard.Modifiers returns the current state of modifiers (instead of the modifier state when a key is pressed), this leads to a really annoying intermittent error for fast typists.

In particular, imagine that someone presses Ctrl + A and releases Ctrl only a few milliseconds after pressing A. Now imagine that the system is under heavy load; the key handler started to execute, but was unloaded for 50 ms. By the time the key handler is executed again, the current state of Ctrl is "released". The key handler will now think that "A" was pressed without Ctrl, and this is bad.

Similarly, if a fast typist got into A, Ctrl + End and my application uses Keyboard.Modifiers , instead, one would observe Ctrl + A ...

In WinForms, the KeyDown tells me the Ctrl state, even if it is already fired by the time the event is processed. How can I get the same behavior in WPF?

Edit : it is possible that Keyboard.Modifiers does not actually retrieve the β€œcurrent” modifier keys, but instead the modifier keys relate to the current message being processed. In WinAPI, this was the difference between the async and non-async key functions. Unfortunately, the documentation does not mention what exactly means "current." If anyone knows, say so.

+7
source share
2 answers

Since the event arguments do not contain any information about the modifier, you can monitor the state in some fields yourself and process both KeyUp and KeyDown to update them accordingly.

eg.

 private bool ctrl = false; private void This_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.LeftCtrl) //or switch, also: `LeftCtrl` & `RightCtrl` are treated as separate keys ctrl = true; //etc.. } private void This_KeyUp(object sender, KeyEventArgs e) { if (e.Key == Key.LeftCtrl) ctrl = false; //etc.. } 

Is this really a good idea, I can’t say ...


If you want to handle key gestures, I would suggest using special methods, such as KeyBindings , they should only work when this gesture. For other input, you can also take a look at TextInput , which is more abstract and returns the text that the input is being entered into.

+3
source

sorry for this destructive answer, but ...

after a little research it becomes clear to me ... the event is called "KeyDown" and not "KeyCombinationDown", so it is completely independent of any modifiers pressed before ...

In fact, there is the right way to achieve your goal: Using Command-Pattern.

You define COMMAND (see google for WPF-Commanding) and add KeyBinding to your application, where you define the key or keys / key combination that will run the command ...

See an example here: http://msdn.microsoft.com/en-us/library/system.windows.input.keybinding.aspx

IMHO, this is the only way and semantically more elegant.

(if this template does not work for you in GENERAL, you may have to use your own api with pinvoke).

greetings.

+2
source

All Articles