表单不响应KeyDown事件

我在Windows窗体项目上工作了一段时间,并决定尝试使用键盘快捷键。 读了一下之后,我想我只需要编写一个事件处理程序,并将其绑定到窗体的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 Studiodevise器的属性面板,然后双击我的窗体的KeyDown事件来生成Form1_KeyDown事件处理程序。 但在testing我的应用程序时,表单完全不响应Ctrl + Alt + O键盘快捷键。 Visual Studiodevise器确实生成了将事件处理程序绑定到表单的代码:

 private void InitializeComponent() { // ... this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); // ... } 

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

另外,我试图在事件绑定调用(如上所示)上设置一个断点,并发现程序到达该断点就好了。 但是我在方法定义本身中设置的断点永远不会到达。

为了确保我正确地执行了前几个步骤,我试着重复下列步骤:

  • 一个新的forms在同一个解决scheme。
    同样的问题:当我按下Ctrl + Alt + O键盘快捷方式时,表单不响应,debugging器甚至没有进入事件处理程序。 试了一遍,它的工作原理。

  • 一个全新的WinForms解决scheme。
    它完美的工作:消息对话框出现( Console.WriteLine()调用也可以)。

所以我很迷茫 什么阻止了这个项目中的所有表单接收KeyDown事件?

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

Form.KeyPreview属性

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

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

在StackOverflow和MSDN 1,2 (包括这里接受的答案)这个问题最常见的build议是快速和容易的:

只要其KeyPreview属性设置为true KeyDown事件就会在Form上触发

这对于大多数目的来说是足够的,但有两个原因是有风险的:

  1. KeyDown处理程序不会看到所有的键 。 具体来说,“你不能看到用于导航的按键types,就像光标键和Tab,Escape和Enter对话框一样。

  2. 拦截关键事件有几种不同的方式,都是按顺序进行的。 KeyDown 最后处理。 因此, KeyPreview不是一个预览,事件可能会在几个停止的方式沉默。

(对于这些点来说,感谢@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事件,而不是像在KeyDown事件处理程序中那样将KeyPressEventArgs.Handled设置为true 。 这里是一个更详细的文章。

尝试将KeyPreview上的KeyPreview属性设置为true。 这对我注册按键很有帮助。