Visual Studio中的KeyDown事件,KeyPress事件和KeyUp事件之间的区别

问题描述:

谁能告诉我KeyDown事件,KeyPress事件和KeyUp事件之间的区别吗?我检查了msdn网站,并没有解释太多。Visual Studio中的KeyDown事件,KeyPress事件和KeyUp事件之间的区别

任何人都可以简单的逻辑意义告诉我什么时候发生了每一件事情?我觉得当按下一个按键时,上述所有事件都会发生。那么它们之间的确切区别是什么。

  • KeyDown:当人按下某个键时(当键盘首次检测到某个键上的手指时,这发生在键被按下时)。

  • KeyPress:当一个键被按下然后释放时发生。

  • KEYUP:发生在当键被释放

你是正确的,当一个键被按下,然后松开,在我上述顺序所有这些事件的发生。

+2

即使reggie没有问这个问题,我在下面添加了一个关于什么时候使用KeyDown和KeyUp的想法。 – 2013-03-01 23:11:52

+3

'KeyPress'描述是错误的。按下键时出现KeyPress,即使永不释放。参见[科迪格雷的答案](http://*.com/a/5871430/1219414)。 – Juan 2015-05-31 20:49:33

嗯,我不知道你仔细检查了MSDN documentation。它规定的顺序三个事件发生相当明确:

重要事件出现以下顺序:

  1. 的KeyDown
  2. 按键响应
  3. KEYUP

当用户按下键盘上的某个键时,立即产生KeyDown,而它们是s直到坚持下来。

KeyPress升高为字符键(不同于KeyDown和KEYUP,这也被升高为非字符键),而键被按下。这是比KeyDown或KeyUp更高级的事件,因此EventArgs中提供了不同的数据。

KeyUp在用户释放键盘上的某个键后产生。

通常,您应该在应用程序中处理KeyUp事件。直到用户释放密钥后之后,操作才能在用户界面中启动。而且由于KeyUp是一个比KeyPress更低级别的事件,所以您总是可以在触手可及的情况下获得大量关于被按下的键的信息,甚至可以用于处理非字符键。


事情需要注意所有这些事件,但是,它们只能由具有焦点的控件引发。这意味着如果表单上的按钮控件目前拥有焦点,那么您的表单的任何关键事件都不会得到提升。对于新来的.NET程序员来说,这经常令人困惑。处理这种情况最好的办法是通过重写形式的ProcessCmdKey method

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    if (keyData == (Keys.Control | Keys.A)) 
    { 
     MessageBox.Show("You pressed Ctrl+A!"); 
    } 
} 
+0

我不知道这个信息有多容易找到?在我看来,如果有一个图表显示每个本地Windows控件的事件发生顺序,那么这将对您有所帮助... – 2012-07-18 19:59:21

+0

或者某种信息聚合网站可以用问答形式轻松表示信息无障碍?去原始文件并不总是理想的解决方案... – weberc2 2012-10-12 12:33:00

+0

@Clay他们没有这样的图表,因为事件/消息的顺序(一般来说)随时都可能发生变化。它是底层控制的实现细节,因此您不能依赖特定的* all *可用消息的顺序。但是,一些特定的消息总是以特定的顺序发送,仅仅是因为它们的设计及其含义。例如,我在这里发出的那些。我想,WinForms文档对关键相关事件有很好的解释。 – 2013-05-22 07:23:53

KeyDown然后KeyPress然后KeyUp是我找到的顺序。

通常,当您想要锁定KeyDown的应用程序时,如果用户在按住Shift键的同时按住多键输入的按键并进行控制键模式修改。 KeyPress适用于简单的键入类型逻辑 - 只需获取按键。 KeyUp被挂钩以便在执行其他处理KeyPress之后执行的逻辑,例如在主逻辑生效后KeyPress之后修改文本编辑框的内容。坦率地说,我没有使用KeyUp那么多,但有时它是在别的东西已经处理之后得到消息的唯一方法,您需要检查/修复发生了什么。

下面是当你不希望使用KEYUP情况:

你有一个列表框,按下一排回车键调用编辑器对话框。问题:如果用户在编辑器的OK按钮上按Enter键,则KeyUp(e.KeyCode = Enter)事件将泄漏回您的列表框,导致编辑器重新打开。如果用户按下编辑器的“确定”按钮上的空格键,则不会发生这种情况;在这种情况下,KeyUp(e.KeyCode = Space)事件在编辑器关闭之前由编辑器处理。

这里有一个选择启发式我用:

If 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 

*如果这个动作是可以在常用的产品中做了一个,说微软Office,如CTRL + A(对于“全选” ),那么我模仿微软的行为,因为这是用户习惯的。

+0

非常有帮助的想法吉姆。但是,这不会导致不一致的体验吗?这可能是不应该发生的,因为对话不应该在关键事件之前采取行动。到目前为止,我一直使用KeyUp(Enter键)来保持一致,但是我遇到了你的状态问题。 – 2013-10-28 21:17:40

+0

在WPF中,可以通过预览事件处理Enter键的“泄漏”,对吗? – Sabuncu 2014-06-20 13:56:51