我已经看到了许多答案,建议使用Keyboard.Modifiers
来确定KeyDown
事件是否适用于具有修饰符集的键。不幸的是,因为Keyboard.Modifiers
返回修饰符的当前状态(而不是按下键时修饰符的状态),这会给快速打字员带来一个非常恼人的间歇性错误。< / p>
具体来说,想象某人按下Ctrl + A,并在按下A后几毫秒才释放Ctrl。现在想象一下系统负载很重;密钥处理程序开始执行但被抢占了50ms。当密钥处理程序再次执行时,Ctrl的当前状态为“已释放”。密钥处理程序现在认为没有Ctrl就按下“A”,这是坏。
同样,如果快速打字员输入A,Ctrl + End并且我的应用程序使用Keyboard.Modifiers
,则可能最终会观察到Ctrl + A ......
在WinForms中,KeyDown
事件告诉我Ctrl 的状态正好,即使它已在事件处理时释放。如何在WPF中获得相同的行为?
编辑:有可能Keyboard.Modifiers实际上并未检索“当前”修饰键,而是修改键与当前正在处理的按键消息相关。在WinAPI中,这是“异步”和非异步键状态函数之间的区别。不幸的是,the documentation没有提到究竟“当前”的含义。如果有人知道,请说出来。
答案 0 :(得分:2)
由于事件args中似乎没有任何修饰符信息,您可以在某些字段中自行跟踪状态,并处理KeyUp
和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
这样的专用方法,它们只应在手势发生时触发。对于其他输入,您可能还需要查看更为抽象的TextInput
,并返回输入转换为的文本。
答案 1 :(得分:2)
实际上有一种正确的方法来实现你的目标: 使用命令模式。
您定义了一个命令(请参阅google for WPF-Commanding)并在您的应用程序中添加一个KeyBinding,您可以在其中定义将启动命令的键或键/键组合......
请参阅此处的示例: http://msdn.microsoft.com/en-us/library/system.windows.input.keybinding.aspx
恕我直言,这是唯一的方式,在语义上也更优雅。
(如果这种模式在GENERAL中不适合你,你可能必须使用带有pinvoke的原生api。)
欢呼声。