我已经看到许多答案,建议使用Keyboard.Modifiers
来确定KeyDown
事件是否用于已设置修饰符的键。不幸的是,因为Keyboard.Modifiers
返回修饰符的当前状态(而不是按下键时的修饰符状态),所以对于快速打字员来说,这会导致一个非常烦人的间歇性错误。
具体来说,假设有人按下Ctrl + A,然后在按下A后仅几毫秒就释放了Ctrl。 key 处理程序开始执行,但被抢占了50ms。到 key 处理程序再次执行时,Ctrl的当前状态已“释放”。 key 处理程序现在会认为在不使用Ctrl的情况下按下了“A”,这很糟糕。
同样,如果快速打字员输入A,然后按Ctrl + End,而我的应用程序使用Keyboard.Modifiers
,则它可能最终会观察到Ctrl + A ...
在WinForms中,KeyDown
事件准确地告诉我Ctrl的状态,即使在处理该事件时它已被释放。如何在WPF中获得相同的行为?
编辑:Keyboard.Modifiers可能实际上没有检索“当前”修饰键,而是与当前正在处理的按键消息相关的修饰键。在WinAPI中,这是“异步”和非异步键状态函数之间的区别。不幸的是,the documentation没有提到“当前”的确切含义。如果有人知道,请这样说。
最佳答案
由于事件args中似乎没有任何修饰符信息,因此您可以在某些字段中自己跟踪状态,并处理KeyUp
和KeyDown
进行相应的更新。
例如
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..
}
我是否可以说这是否真的是个好主意...
如果您想处理关键手势,我建议您使用诸如
KeyBindings
之类的专用方法,它们仅应在手势发生时触发。对于其他输入,您可能还想看看 TextInput
,它更加抽象并返回输入被翻译成的文本。关于wpf - 如何正确检索WPF KeyDown事件中的修饰键?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12125590/