我正在构建一个小型Forms应用程序,我刚刚启动它 . 但我有这个问题:如果我将一个控件放到窗体上,KeyDown事件不会触发 . 我知道KeyPreview属性,并将其设置为true . 但这没有帮助... :(我也试图把焦点放在主要形式上,也没有成功 .
有什么想法吗?
编辑:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
KeyDown += new KeyEventHandler(Form1_KeyDown);
this.KeyPreview = true;
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Left: MessageBox.Show("Left");
break;
case Keys.Right: MessageBox.Show("Right");
break;
}
}
}
4 回答
箭头键是一种由控件自动处理的特殊键 . 因此,如果您想让它们引发KeyDown事件,您可以:
1)在表单的每个控件中重写isInputKey方法
要么
2)处理PreviewKeyDown事件并将IsInputKey属性设置为true
更多信息可以在here找到 .
我知道WonderCsabo已经解决了他的问题,但是有人给了它一个赏金,因为它有同样的问题并且没有选择答案 . WonderCsabo也请发布您的解决方案作为答案 .
您观察到的行为的原因是特殊键,如TAB,上/下/左/右箭头,PAGE UP / DOWN,HOME,END等,通常被通用控件视为“输入键” .
例如,ARROW键被TabControl视为“输入键”,因为这些键允许您更改选定的TabPage . 多行TextBox存在类似的行为,其中ARROWS键允许您移动文本光标 .
我认为由于同样的原因,你所拥有的Rumba Mainframe控件做同样的事情 . 您可以尝试覆盖它并更改IsInputKey方法的实现或处理PreviewKeyDown事件并将IsInputKey属性设置为true .
有关详细信息,请参阅Control.IsInputKey Method和Control.PreviewKeyDown Event的文档
我已经评论过我的解决方案,但我也将其作为答案发布,因此很容易找到 .
如果您使用WPF,则可以轻松捕获所需的事件,因为WPF使用routed event system来分派事件 . 在winforms中,我推荐以下两种方式之一:
1.使用Application.AddMessageFilter方法:
定义消息过滤器类:
因此,您有一个类,Windows窗体中的每个消息都通过它 . 你可以随意为活动做任何事情 . 如果PreFilterMessage方法返回true,则表示不应将事件分派给它的respcetive控件 .
(请注意,
Keys
枚举中的值几乎是virtual key codes的必要条件)在此之前,您必须将其添加到应用程序的消息过滤器:
过滤器仅在
Form1
的生命周期内有效 .注意:这将捕获任何形式的事件!如果您希望它仅适用于一个表单,请将表单传递给过滤器类,并将其Handle属性与
m.HWnd
进行比较PreFilterMessage
2.使用Windows挂钩:
这是一种更先进,更复杂(和低级别)的方法 . 它需要更多代码 . 我写了一个
HookManager
类,这个过程非常简单 . 我要把这个类发布到github并写一篇关于它的文章 .