KeyDown
事件、KeyPress
事件和 KeyUp
事件之间的区别吗?我查看了MSDN网站,但没有太多解释。请问这些事件发生的时机在逻辑上简单易懂的情况下能否说明一下?我感觉所有这些事件都是在按下键盘按键时发生的。那么它们之间的确切区别是什么呢?
KeyDown
事件、KeyPress
事件和 KeyUp
事件之间的区别吗?我查看了MSDN网站,但没有太多解释。MSDN文档清晰地说明了三个事件的顺序:
按键事件按照以下顺序发生:
- KeyDown
- KeyPress
- KeyUp
KeyDown
在用户按下键盘上的键时立即触发,当用户仍然按住该键时。
KeyPress
只对字符键触发(与KeyDown和KeyUp不同,它们也对非字符键触发),而且在按下键时触发。这是比KeyDown或KeyUp更高级的事件,因此EventArgs
中提供了不同的数据。
KeyUp
在用户释放键盘上的键后触发。
通常情况下,应该处理KeyUp
事件。在用户释放键后再启动UI操作。由于KeyUp
是比KeyPress
低级的事件,因此您将始终可以获得有关按下的键的丰富信息,甚至可以用于处理非字符键。
但要注意,所有这些事件都只能被具有焦点的控件触发。这意味着如果您的窗体上有一个按钮控件当前具有焦点,那么您的窗体的任何按键事件都不会触发。这经常让.NET新手感到困惑。处理这个最好的方法是重写窗体的ProcessCmdKey
方法:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.A))
{
MessageBox.Show("You pressed Ctrl+A!");
}
return base.ProcessCmdKey(ref msg, keyData);
}
按键按下事件(KeyDown):当用户按下一个按键时发生,指的是当键盘检测到手指按在按键上时发生。
按键按下并释放事件(KeyPress):当按键被按下并释放时发生。
按键释放事件(KeyUp):当用户松开按键时发生。
您说得对,所有这些事件都发生在按键按下然后释放的顺序中。
KeyPress
只会触发一次。如果按键被按住,KeyDown
会持续触发。 - ourmandaveIf I'm handling the Enter key and I need to guard against a case like the one above
then I use KeyDown
Else if I'm handling key combinations (e.g. CTRL+C)
then I favor* KeyDown (KeyUp can make these awkward)
Else if I am allowing press & hold autorepeat
then I use KeyDown
Else
I use KeyUp
*如果某个行为在常用产品中(如Microsoft Office)可以完成,例如CTRL+A(选定全部),那么我会模仿Microsoft的行为方式,因为用户已经习惯了这种方式。
除了其他答案之外:
在尝试确定将动作连接到这些事件中的哪一个时,请注意,当按键按下时将多次触发KeyDown
事件。有时您需要此行为,有时不需要。基于此,我建议以下用法(根据我的经验):
(事件触发顺序)
KeyDown
发生时间: 按钮按下并持续按下时
用途: 即刻在按钮按下时执行操作甚至多次执行操作
示例: 使用箭头键移动光标
.
KeyPress
发生时间: 按下字符键(更高级别的事件)
用途: 与输入文本相关的任何内容
示例: 处理文本框输入
.
KeyUp
发生时间: 松开键盘按键
用途: 执行关键动作,每个击键只应发生一次
示例: 将数据写入文件
KeyDown
、KeyPress
和KeyUp
的顺序是我发现的。
通常情况下,当用户按住控制键进行多模输入时(例如shift-click操作),你需要挂钩KeyDown
;KeyPress
用于简单的按键输入逻辑,只需获取按键;KeyUp
被挂钩以在其他东西处理KeyPress
后执行逻辑,例如修改文本编辑框的内容。老实说,我并不经常使用KeyUp
,但有时它是获取消息的唯一方法,因为其他东西已经处理了KeyPress
,你需要检查/修复发生的事情。
KeyUp
,当用户按住键时你将不会得到重复的响应。并且,仅在释放键时才发生某些事情是不正确的说法。这对于点击按钮是正确的,但对于按键则不是。 - Dave CousineauKeyPreview
属性设置为 true,您可以获取一个表单来响应通常由表单上的控件处理的关键事件。 - bmadtigerreturn base.ProcessCmdKey(ref msg, keyData);
- Cody Gray