如何在WPF中检测修改键状态?

174

我是否可以使用一些全局结构来判断控制(Control)、Shift和Alt键是否按下?比如在TreeViewMouseDown事件中。

如果可以,具体该怎么做呢?

6个回答

292

使用类Keyboard。 通过使用Keyboard.IsKeyDown,您可以检查控件、Shift和Alt是否已按下。

对于Shift:

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 */ }

136

还有这个:

// 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
36
请注意,上面示例中的比较会产生不同的结果!由于 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+右箭头”。 - ANeves
1
@ANeves 有趣,Keyboard.Modifiers 显示为 None - Chuck Savage

9
    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”,在我的情况下) - Josh

6

这是我处理它的方式(使用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,可能是因为修饰键的缘故吧?但当我搜索修饰键+键时,这对我来说非常完美无缺。

谢谢 - Keyboard.IsKeyDown是我一直在寻找的方法,可以同时扫描两个按键。为了捕获Shift-Tab,我使用了e.Key == Key.Tab以及左右Shift修饰符枚举。不幸的是,我无法解释为什么你需要使用e.SystemKey。 - undefined

5

部分参考@Josh的内容,有些类似于@Krushik,并且参考了一个关于KeyEventArgs.systemKey和KeyEventArgs.Key的区别的问题(回答为什么Josh必须使用SystemKey);在其中,对于修改键(如Alt),e.Key返回Key.System,因此'real' key在e.SystemKey中。

解决这个问题的方法是先获取'real' key,然后执行条件语句:

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

谢谢你回答我回答中嵌入的问题 ;) 我从来没有真正查过,知道了很好! - Josh

-1

还有:

如果 My.Computer.Keyboard.ShiftKeyDown 则...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接