KeyDown : 识别多个键

Posted

技术标签:

【中文标题】KeyDown : 识别多个键【英文标题】:KeyDown : recognizing multiple keys 【发布时间】:2010-11-18 22:25:41 【问题描述】:

我如何确定在KeyDown 中按下了 CtrlUp

private void listView1_KeyDown(object sender, KeyEventArgs e)

    if (e.KeyCode == Keys.Control && e.KeyCode == Keys.Up)
    
        //do stuff
    
    

不能工作,因为从来没有在同一秒内同时按下两个键。你总是先按 Ctrl 然后另一个...

【问题讨论】:

【参考方案1】:

您可以像这样检查 KeyEventArgs 的修饰符:

private void listView1_KeyDown(object sender, KeyEventArgs e)

    if (e.KeyCode == Keys.Up && e.Modifiers == Keys.Control)
    
        //do stuff
    
  

MSDN reference

【讨论】:

这在我的键盘上从来都不是真的——例如,如果我按下 LShiftKey 和 Keys.Up,它 e.Shift 永远不会是真的,并且 e.Modifiers 将永远保持为 None。知道为什么吗? 似乎箭头键在某些方面很特别。这个问题提供了一些见解:***.com/questions/1646998/… 我只发现有e.Key,没有e.KeyCode。也没有 e.Modifier。 @KMC 令人困惑的是,有两个不同的KeyEventArgs。我假设您正在使用来自Windows.UI.Core 的那个,来自CoreWindow 事件。这个答案是关于一个不同的事件。【参考方案2】:

来自MSDN page on KeyEventArgs:

if (e.KeyCode == Keys.F1 && (e.Alt || e.Control || e.Shift))

    //Do stuff...

【讨论】:

【参考方案3】:

您可以尝试使用Keyboard 对象来检测IsKeyDown 属性。此外,如果您不希望浏览器快捷方式被覆盖,您可以将Handled 属性设置为 true。但是在覆盖浏览器快捷方式时要小心,因为它可能会导致混淆。

private void Page_KeyDown(object sender, KeyEventArgs e)

    // If leftCtrl + T is pressed autofill username
    if (Keyboard.IsKeyDown(Key.T) && Keyboard.IsKeyDown(Key.LeftCtrl))
    
        txtUser.Text = "My AutoFilled UserName";
        e.Handled = true;
    

【讨论】:

注意:这是 WPF。 @TaW - 我们正在运行 XBAP 应用程序(在 Internet Explorer 中运行的 WPF)。因此,在这种情况下,您仍然需要将击键设置为Handled,否则 IE 会选择它。 XBAP 不是一个使用非常广泛的框架,但我想我会让你知道我为什么要讨论处理浏览器:) - 谢谢。【参考方案4】:

KeyEventArgs 中有属性 CtrlAltShift 显示这些按钮是否被按下。

【讨论】:

谢谢这工作完美! if(e.Control && e.KeyCode == Keys.A)【参考方案5】:
private void listView1_KeyDown(object sender, KeyEventArgs e)

    if (e.Key == Key.Up && Keyboard.IsKeyDown(Key.LeftCtrl))
    
         //do stuff
    

此代码仅在您先按 LeftCtrl,然后按“UP”时才有效。 如果顺序不重要,我推荐一个:

if ((Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))&& Keyboard.IsKeyDown(Key.Z))

    //do stuff

在这种情况下,两个 Ctrl 都被考虑在内,并且顺序无关紧要。

【讨论】:

【参考方案6】:

您可以使用 ModifierKeys 属性:

if (e.KeyCode == Keys.Up && (ModifierKeys & Keys.Control) == Keys.Control)

    // CTRL + UP was pressed

请注意,ModifierKeys 值可以是值的组合,因此如果您想检测是否按下了 CTRL,而不管 SHIFT 的状态如何ALT 键,您将需要按照我上面的示例执行按位比较。如果你想确保没有按下其他修饰符,你应该检查是否相等:

if (e.KeyCode == Keys.Up && ModifierKeys == Keys.Control)

    // CTRL + UP was pressed

【讨论】:

在HERE,您说数据在KeyData字段中。这里没有人提到KeyData。这些答案不正确吗? 不错@jp2code! ModifierKeysControl 上的一个属性(例如windows 窗体),它将为您提供有关当前 被按下的修饰键的信息。键事件附带的KeyData 包含有关与导致事件的键一起按下的修饰键的信息。回想起来,我会说ModifierKeys 与按钮单击或类似事件一起更有趣,在关键事件中使用KeyData 会更准确。【参考方案7】:

这肯定会奏效。小心处理KeyUp 事件而不是keyDown

private void mainForm_KeyUp(object sender, KeyEventArgs e)
    
        if (e.Modifiers == Keys.Control && e.KeyCode == Keys.A)
        
             //insert here
        
    

对我来说,keyDown 不起作用,keyUp 对相同的代码起作用。

我不知道为什么,但似乎是因为keyDown 事件在你按下任意键后直接发生,即使那是 ctrl 键,所以如果你按下 ctrl kbd>+Up 您将在 UP 键之前按 ctrl 键,因此事件将在您按下另一个之前发生,同时按下第二个键将再次触发事件。

虽然使用KeyUp不会触发事件,直到你松开按键,所以你可以按ctrl,再按第二个键,会触发一个事件。

【讨论】:

【参考方案8】:

我测试了下面的代码。它有效...

private void listView1_KeyDown(object sender, KeyEventArgs e)
    
        if ((int) e.KeyData == (int) Keys.Control + (int) Keys.Up)
        
            MessageBox.Show("Ctrl + Up pressed...");
        
    

【讨论】:

【参考方案9】:

在尝试检测 [Alt][Right] 时,我花了一段时间才找到最终需要的提示。我在这里找到了它:https://social.msdn.microsoft.com/Forums/vstudio/en-US/4355ab9a-9214-4fe1-87ea-b32dfc22946c/issue-with-alt-key-and-key-down-event?forum=wpf

在我使用的 Shortcut 助手类中归结为类似这样的内容:

public Shortcut(KeyEventArgs e) : this(e.Key == System.Windows.Input.Key.System ? e.SystemKey : e.Key, Keyboard.Modifiers, false)  

public Shortcut(Key key, ModifierKeys modifiers, bool createDisplayString)

    ...
 

在“重新映射”原始值之后(注意e.Key == System.Windows.Input.Key.System ? e.SystemKey : e.Key 部分),可以照常进行进一步处理。

【讨论】:

【参考方案10】:

if (e.Control && e.Shift && e.KeyCode == Keys.A)

【讨论】:

在回答旧帖子时,如果您可以为您的回答提供一些上下文而不仅仅是代码,这将很有帮助,因为它可能对其他人更有用。【参考方案11】:

KeyDown 事件将只保存最近按下的键的信息。我已经成功构建了一个字符串,其中包含所有最新的按键连接在一起。

如果按下“Control”键,或者字符串长度超过 10 个字符,我会清除字符串。

每次检查字符串,然后在执行任务后执行任务,可以很好地使用应用程序中的秘密热键功能。

    private void ConfigurationManager_KeyDown(object sender, KeyEventArgs e)
    
        string currentKey = e.KeyCode.ToString().ToLower();

        if ((currentKey == "controlkey") || (hotKeyList.Length > 10))
        
            hotKeyList = "";
        
        else
        
            hotKeyList += currentKey;
        

        if ((hotKeyList == "int") && (!adminLogin))
        
            hotKeyList = "";
            adminLogin = true;
            AdminLoginEvn();
        
    

对于上面的函数,我的热键将是“Control(清除字符串)+ i + n + t”来触发我的 AdminLoginEvn 方法。 adminLogin 布尔值被合并,所以我只在应用程序打开时运行一次 AdminLoginEvn。

【讨论】:

【参考方案12】:

你可以试试我的工作代码:

private void listView1_KeyDown(object sender, KeyEventArgs e)

    if (e.KeyCode == Keys.Up)
    
        if(e.Alt==true)
            //do your stuff
        
    

我使用此代码是因为我不知道为什么使用时:

(e.Keycode == Keys>up && e.Alt==true)

没用。

【讨论】:

【参考方案13】:

您必须记住按下的键(即在布尔数组中)。并在按下 (keydown) 时将位置设置为 1,在向上时将位置设置为 0。

这样您可以跟踪多个键。我建议只为特殊键做一个数组

所以你可以这样做:

 if (e.KeyCode == Keys.Control)
 
        keys[0] = true;
 
// could do the same with alt/shift/... - or just rename keys[0] to ctrlPressed

if (keys[0] == true && e.KeyCode == Keys.Up)
 doyourstuff

【讨论】:

以上是关于KeyDown : 识别多个键的主要内容,如果未能解决你的问题,请参考以下文章

vb.net 方向键不能触发 keydown 事件

在 C# 中的 keydown 上播放键值

将 jQuery .keydown() 限制为仅特定键

防止表单提交字段输入键keydown? [复制]

KeyPress和KeyDown/KeyUp

如何从 WPF 页面触发 KeyDown 事件