I've seen a number of answers suggesting the use of Keyboard.Modifiers
to determine whether a KeyDown
event is for a key that had a modifier set. Unfortunately, because Keyboard.Modifiers
returns the current state of the modifiers (instead of the state of the modifier when the key was pressed), this results in a really annoying intermittent bug for quick typists.
Specifically, imagine someone presses Ctrl+A, and releases Ctrl only a few milliseconds after pressing A. Now imagine that the system was under heavy load; the key handler started executing but was preempted for 50ms. By the time the key handler is executing 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 enters A, Ctrl+End and my application uses Keyboard.Modifiers
, it could instead end up observing Ctrl+A...
In WinForms, the KeyDown
event tells me the state of Ctrl exactly, even if it's already released by the time the event is being handled. How can I get this same behaviour in WPF?
Edit: it's possible that Keyboard.Modifiers doesn't actually retrieve the "current" modifier keys, but instead the modifier keys as related to the key down message currently being processed. In WinAPI, this was the distinction between "async" and non-async key state functions. Unfortunately, the documentation doesn't mention what exactly "current" means. If anyone knows, please say so.
As there does not appear to be any modifier information in the event args you could keep track of the state yourself in some fields and handling both KeyUp
and KeyDown
to update them accordingly.
e.g.
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..
}
Whether this is actually a good idea i cannot say...
If you want to handle key gestures i would suggest using dedicated methods like KeyBindings
they should only fire when the gesture happened. For other input you may also want to have a look at TextInput
which is more abstract and returns the text that the input is translated to.
sorry for this destructive answer but...
after a little bit of research it becomes clear to me... the event is called "KeyDown" not "KeyCombinationDown" so it is totally independent of any Modifiers pressed BEFORE...
Actually there is a right way for achieve your goal: Using the Commanding-Pattern.
You define a COMMAND (see google for WPF-Commanding) and add a KeyBinding to your application, where you define the key or the keys/key-combination which will fire up the command...
See the example here: http://msdn.microsoft.com/en-us/library/system.windows.input.keybinding.aspx
IMHO, this is the only way and semantically more elegant, too.
(if this pattern will not be working for you in GENERAL, you maybe have to use native api with pinvoke).
cheers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With