我已经看到许多答案,建议使用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中似乎没有任何修饰符信息,因此您可以在某些字段中自己跟踪状态,并处理KeyUpKeyDown进行相应的更新。

例如

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/

10-10 20:13