表单没有响应KeyDown事件

时间:2010-07-03 20:07:59

标签: c# .net winforms

我在Windows Forms项目上工作了一段时间,我决定尝试使用键盘快捷键。经过一番阅读后,我想我必须编写一个事件处理程序并将其绑定到表单的KeyDown事件:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.Alt && e.KeyCode == Keys.O)
    {
        MessageBox.Show("Ctrl+Alt+O: magic!");
    }
}

我这样做是打开Visual Studio设计器的Properties面板的好方法,然后双击我的表单的KeyDown事件来生成Form1_KeyDown事件处理程序。但在测试我的应用程序时,表单根本不响应 Ctrl + Alt + O 键盘快捷键。 Visual Studio设计器确实生成了将事件处理程序绑定到表单的代码:

private void InitializeComponent()
{
    // ...

    this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);

    // ...
}

所以我尝试向处理程序添加一个Console.WriteLine()调用以检查它是否被调用,但是也没有运气。

另外,我试图在事件绑定调用上设置断点(如上所示),发现程序到达该断点就好了。但是我从未在方法定义中设置任何断点。

为了确保我正确地执行了前几个步骤,我尝试用以下方法重复它们:

  • 同一解决方案中的新表单。
    同样的问题:当我按下 Ctrl + Alt + O 键盘快捷键并且调试器不是时,表单没有响应甚至走进事件处理程序。再次尝试这个并且它可以工作。

  • 全新的WinForms解决方案。
    它完美运行:出现消息对话框(Console.WriteLine()调用也有效)。

所以我在这里迷失了。是什么阻止了这个项目中的所有表单接收KeyDown事件?

3 个答案:

答案 0 :(得分:136)

您的表单是否将KeyPreview属性设置为true?

  

Form.KeyPreview Property

     

获取或设置一个值,该值指示表单是否将接收密钥   将事件传递给具有焦点的控件之前的事件。

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

答案 1 :(得分:34)

StackOverflow和MSDN 12 (包括此处接受的答案)对此问题的最常见建议是快速而简单:

  只要KeyDown属性设置为Form

,就会在KeyPreview上触发

true个事件

这对于大多数用途来说已经足够了,但由于两个原因它存在风险:

  1. KeyDown处理程序do not see all keys。具体来说,“您无法看到用于导航的击键类型。如光标键和Tab,Escape和Enter用于对话框。”

  2. 拦截关键事件有几种不同的方法,它们都按顺序发生。最后处理KeyDown 。因此,KeyPreview并不是预览,并且在途中可以在几个站点停止活动。

  3. (感谢@HansPassant获得这些积分。)

    而是覆盖Form中的ProcessCmdKey

    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
        if (keyData == Keys.Up)
        {
            // Handle key at form level.
            // Do not send event to focused control by returning true.
            return true;
        }
      return base.ProcessCmdKey(ref msg, keyData);
    }
    

    这样,方法可以看到所有键,并且该方法排在第一位以查看事件。

    请注意,您仍然可以控制焦点控件是否看到KeyDown事件。只需返回true即可阻止后续的KeyDown事件,而不是像KeyPressEventArgs.Handled事件处理程序那样将true设置为KeyDownHere是一篇详细介绍的文章。

答案 2 :(得分:19)

尝试将表单上的KeyPreview属性设置为true。这对我来说是注册按键的。