如何检测WPF中的修饰键状态?


150

每当需要访问Control,Shift,Alt按钮是否关闭时,是否可以使用一些全局构造?例如的内部MouseDown事件TreeView

如果可以,怎么办?

Answers:


257

使用类Keyboard。使用Keyboard.IsKeyDown可以检查Control,Shift,Alt现在是否关闭。

对于班次:

if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ /* Your code */ }

对于控制:

if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ /* Your code */ }

对于Alt:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }

124

还有:

// Have to get this value before opening a dialog, or user will have released the control key
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{

}

13
更好的解决方案。它还允许您一次检查所有修饰符。如果您想处理Ctrl + F,则不需要处理Ctrl + Shift + F,因此您只需检查(e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)而不是检查其他所有内容即可
ygoe 2013年

35
请注意,以上示例中的比较会产生不同的结果!由于ModifierKeys枚举具有Flags属性,因此您可以在枚举中包含值的任意组合。如果只想抓住按下的Shift键,请使用以下Keyboard.Modifiers == ModifierKeys.Shift语句。如果您想抓住Shift键却不在乎是否同时按下了其他修饰符,请使用(Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift或更好的HasFlag语法Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B

4
我无法使用此方法捕获Windows键修饰符。(CTRL工作正常。)我试图抓住WIN+RightArrow
ANeves 2014年

1
@ANeves有趣,Keyboard.Modifiers显示为None
Chuck Savage

8
    private bool IsShiftKey { get; set; }

    private void OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        IsShiftKey = Keyboard.Modifiers == ModifierKeys.Shift ? true : false;

        if ((Key.Oem3 == e.Key || ((IsShiftKey && Key.Oem4 == e.Key) || (IsShiftKey && Key.Oem6 == e.Key) || (IsShiftKey && Key.Oem5 == e.Key)) && (validatorDefn as FormatValidatorDefinition).format == "packedascii"))
        {
           e.Handled = true;
        }
    }

2
注释和代码对答案都更好。请提供一些背景信息。
克里斯(Chris

1
将其添加为属性的好主意
RollRoll

1
当我使用PreviewKeyDown查找Alt +另一个键时,我不得不使用e.SystemKey而不是e.Key(在我使用alt +另一个字符的情况下,e.Key的值为“ System”)
乔什

3

这就是我的处理方式(使用PreviewKeyDown),假设我们正在寻找Alt + R ...

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)
       && e.SystemKey == Key.R)
    {
       //do whatever
    }
}

也许有人可以弄清楚为什么我不得不使用e.SystemKey而不是仅仅使用e.Key,也许是由于修改器的缘故?但这在搜索修饰符+键时对我来说是完美的。


0

以及:

如果My.Computer.Keyboard.ShiftKeyDown然后...

My.Computer.Keyboard.CtrlKeyDown

我的电脑键盘.AltKeyDown


0

部分是从@Josh借用的,与@Krushik有点类似,并且还引用了有关KeyEventArgs.systemKey和KeyEventArgs.Key之间区别的问题(回答为何Josh必须使用SystemKey);其中,使用修饰键(例如Alt),e.Key返回Key.System,因此“真实”键在e.SystemKey中。

一种解决方法是,首先获取“真实”密钥,然后执行条件操作:

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    // Fetch the real key.
    var key = e.Key == Key.System ? e.SystemKey : e.Key;

    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
        && key == Key.Return)
    {
        // Execute your code.
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.