我在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事件?
答案 0 :(得分:136)
您的表单是否将KeyPreview属性设置为true?
Form.KeyPreview Property
获取或设置一个值,该值指示表单是否将接收密钥 将事件传递给具有焦点的控件之前的事件。
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
答案 1 :(得分:34)
StackOverflow和MSDN 1,2 (包括此处接受的答案)对此问题的最常见建议是快速而简单:
只要KeyDown
属性设置为Form
,就会在KeyPreview
上触发
true
个事件
这对于大多数用途来说已经足够了,但由于两个原因它存在风险:
KeyDown
处理程序do not see all keys。具体来说,“您无法看到用于导航的击键类型。如光标键和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
事件,而不是像KeyPressEventArgs.Handled
事件处理程序那样将true
设置为KeyDown
。 Here是一篇详细介绍的文章。
答案 2 :(得分:19)
尝试将表单上的KeyPreview
属性设置为true。这对我来说是注册按键的。