表单不响应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
上触发
这对于大多数目的来说是足够的,但有两个原因是有风险的:
-
KeyDown
处理程序不会看到所有的键 。 具体来说,“你不能看到用于导航的按键types,就像光标键和Tab,Escape和Enter对话框一样。 -
拦截关键事件有几种不同的方式,都是按顺序进行的。
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。 这对我注册按键很有帮助。