如何在 WPF KeyDown 事件中正确检索修饰键?

2024-01-05

我看过很多建议使用的答案Keyboard.Modifiers来确定是否KeyDown事件适用于设置了修饰符的键。不幸的是,因为Keyboard.Modifiers返回current修改器的状态(而不是按下按键时修改器的状态),这会导致快速打字员遇到真正烦人的间歇性错误。

具体来说,假设有人按下 Ctrl+A,并在按下 A 后仅几毫秒就释放了 Ctrl。现在假设系统处于重负载状态;密钥处理程序开始执行,但被抢占了 50 毫秒。当密钥处理程序再次执行时,currentCtrl 的状态为“释放”。键处理程序现在会认为在没有 Ctrl 的情况下按下了“A”,这是bad.

同样,如果快速打字员输入 A、Ctrl+End 并且我的应用程序使用Keyboard.Modifiers,它最终可能会观察 Ctrl+A...

在 WinForms 中,KeyDown事件告诉我 Ctrl 的状态exactly,即使在处理事件时它已经被释放。如何在 WPF 中获得相同的行为?

Edit:Keyboard.Modifiers 实际上可能并未检索“当前”修饰键,而是检索与当前正在处理的按键按下消息相关的修饰键。在 WinAPI 中,这是“异步”和非异步键状态函数之间的区别。很遗憾,文档 http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.modifiers.aspx没有提到“当前”到底是什么意思。如果有人知道,请说出来。


由于事件参数中似乎没有任何修饰符信息,因此您可以自己跟踪某些字段中的状态并处理这两个字段KeyUp and KeyDown相应地更新它们。

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..
}

我不能说这是否真的是一个好主意......


如果您想处理关键手势,我建议使用专用方法,例如KeyBindings http://msdn.microsoft.com/en-us/library/system.windows.input.keybinding.aspx他们应该只在手势发生时才开火。对于其他输入,您可能还想看看TextInput http://msdn.microsoft.com/en-us/library/system.windows.uielement.textinput.aspx它更抽象,并返回输入翻译后的文本。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 WPF KeyDown 事件中正确检索修饰键? 的相关文章

随机推荐