.NET中的KeyDown和KeyPress有什么区别?


Answers:


308

显然对此有很多误解!

KeyDown和之间的唯一实际区别在于,KeyPressKeyPress中继了按键产生的字符,并且仅在有按键时才调用。

换句话说,如果您按下A键盘,则会得到以下事件序列:

  1. KeyDown:KeyCode = Keys.A,KeyData = Keys.A,修饰符= Keys.None
  2. KeyPress:KeyChar ='a'
  3. KeyUp:KeyCode = Keys.A

但是,如果按Shift+ A,您将得到:

  1. KeyDown:KeyCode = Keys.ShiftKey,KeyData = Keys.ShiftKey,Shift,修饰符= Keys.Shift
  2. KeyDown:KeyCode = Keys.A,KeyData = Keys.A | Keys.Shift,修饰符= Keys.Shift
  3. KeyPress:KeyChar ='A'
  4. KeyUp:KeyCode = Keys.A
  5. KeyUp:KeyCode = Keys.ShiftKey

如果按住键一会,您将得到类似以下内容的信息:

  1. KeyDown:KeyCode = Keys.ShiftKey,KeyData = Keys.ShiftKey,Shift,修饰符= Keys.Shift
  2. KeyDown:KeyCode = Keys.ShiftKey,KeyData = Keys.ShiftKey,Shift,修饰符= Keys.Shift
  3. KeyDown:KeyCode = Keys.ShiftKey,KeyData = Keys.ShiftKey,Shift,修饰符= Keys.Shift
  4. KeyDown:KeyCode = Keys.ShiftKey,KeyData = Keys.ShiftKey,Shift,修饰符= Keys.Shift
  5. KeyDown:KeyCode = Keys.ShiftKey,KeyData = Keys.ShiftKey,Shift,修饰符= Keys.Shift
  6. KeyDown:KeyCode = Keys.A,KeyData = Keys.A | Keys.Shift,修饰符= Keys.Shift
  7. KeyPress:KeyChar ='A'
  8. KeyDown:KeyCode = Keys.A,KeyData = Keys.A | Keys.Shift,修饰符= Keys.Shift
  9. KeyPress:KeyChar ='A'
  10. KeyDown:KeyCode = Keys.A,KeyData = Keys.A | Keys.Shift,修饰符= Keys.Shift
  11. KeyPress:KeyChar ='A'
  12. KeyDown:KeyCode = Keys.A,KeyData = Keys.A | Keys.Shift,修饰符= Keys.Shift
  13. KeyPress:KeyChar ='A'
  14. KeyDown:KeyCode = Keys.A,KeyData = Keys.A | Keys.Shift,修饰符= Keys.Shift
  15. KeyPress:KeyChar ='A'
  16. KeyUp:KeyCode = Keys.A
  17. KeyUp:KeyCode = Keys.ShiftKey

请注意,它KeyPress发生 KeyDown之间KeyUp而不是后面KeyUp,正如许多其他答案所述,KeyPress在不生成字符时不会调用该函数,并且KeyDown在按住键时重复该操作,这也与许多其他答案相反。

不会直接导致调用的键示例KeyPress

  • ShiftCtrlAlt
  • F1 通过 F12
  • 方向键

确实会导致调用的键示例KeyPress

  • A通过Z0通过9等等。
  • Spacebar
  • Tab (KeyChar ='\ t',ASCII 9)
  • Enter (KeyChar ='\ r',ASCII 13)
  • Esc (KeyChar ='\ x1b',ASCII 27)
  • Backspace (KeyChar ='\ b',ASCII 8)

对于好奇,KeyDown大致关联到WM_KEYDOWNKeyPressWM_CHARKeyUpWM_KEYUPWM_KEYDOWN 可以调用的次数少于键重复的次数,但是它会发送一个重复计数,IIRC,WinForms使用该计数每次重复恰好生成一个KeyDown。


2
很好的解释,不过,有一点警告,Escape不会在Chrome上触发KeyPress(不确定其他按键)。
巴尼

3
@BarnabasSzabolcs:Chrome是否运行.NET?
P Daddy

@PDaddy ups,我已经忽略了,我认为它是javascript:D,但是样式有点古怪:P,但是看起来规则却非常相似:DD ...有趣的是,这个答案对我有很大帮助。欢呼:)
巴尼(Barney)

@PDaddy我知道至少Tab默认不会触发KeyDown或KeyUp
PsychoData 2014年

@PsychoData:这是因为Tab键更改了焦点,因此未将其作为输入处理。如果ProcessDialogKeykeyDatais Keys.Tab或时重写并返回false Keys.Shift | Keys.Tab,那么您将在(On)Key(Down | Press | Up)中看到Tab键。
P Daddy

73

非字符键不会引发KeyPress事件。但是,非字符键会引发KeyDown和KeyUp事件。

http://msdn.microsoft.com/zh-CN/library/system.windows.forms.control.keypress.aspx


17
其他大多数答案在某种程度上都是错误的,但是这个答案最接近现实。KeyPress仅针对字符键提高,并且服从键盘键入延迟/重复的设置。事件的实际顺序是:1)KeyDown 2)字符键KeyPress一次或多次(取决于系统设置和键的按住时间)3)KeyUp
Filip Navara

我没有销售代表,但是有人可以破坏Wiki并将上述评论的内容和接受的答案结合起来吗?
乔什·科德洛夫

11
Filip Navara的评论并不完全正确。如果按住某个键,则会得到KeyDown,KeyPress,KeyDown,KeyPress,KeyDown,KeyPress KeyUp。每次重复调用KeyDown。
P爸爸2009年

9

KeyPress仅由可打印字符触发,并在KeyDown事件后触发。根据键入延迟设置,可以有多个KeyDown和KeyPress事件,但只有一个KeyUp事件。

KeyDown
KeyPress
KeyUp


您很接近,但是顺序不对。
P Daddy

@P Daddy-我已经更正了它,应该在退出内存之前仔细检查。
stevehipwell,2009年

@ Stevo3000,仅供参考:不可打印的Unicode字符也会触发KeyPress事件。我有一个应用程序,该程序读取由条形码阅读器插入到文本框中的数据,并且该阅读器包含不可打印的Unicode字符。
杰夫·拉法

@jlafay-不是根据MSDN 。非字符键不会引发KeyPress事件。但是,非字符键会引发KeyDown和KeyUp事件。
stevehipwell

@ Stevo3000,我不确定条形码扫描仪如何将文本输入到文本框中,但是KeyPress会触发它发送的特殊字符。该值以不可打印字符开头,并以不可打印字符结尾。因此,我不确定这是否正确。也许我将看一下包含有IL Spy事件的.Net程序集,以便更好地了解实际检测到的内容。
杰夫·拉法

5

KeyPress比KeyDown(和KeyUp)具有更高的抽象级别。KeyDown和KeyUp与硬件相关:键盘上按键的实际操作。KeyPress更是“我从键盘上收到了一个字符”。


4

从MSDN:

关键事件按以下顺序发生:

  1. 按键

  2. 按键

  3. 按键

此外,KeyPress还使您有机会将操作声明为“已处理 ”,以防止其执行任何操作。


FYI,KeyDown和KeyUp还具有一个Handled属性,您可以设置该属性,使其不在KeyPress和其他按键事件之间。
杰夫·拉法

FWIW尽管KeyUp像KeyDown一样获取KeyEventArgs参数,但它的Handled属性对于KeyUp无效(SuppressKeyPress也无效)。
JonP



1

来自博客开发者

为了理解按键和按键之间的区别,理解“字符”“按键”之间的区别是有用的。一个“关键”是计算机的键盘上的物理按键,而一个“字”是按一个按钮输入的符号。从理论上讲,该keydown和KeyUp事件表示按键被按下或释放,而按键事件表示字符被输入。该理论的实现并非在所有浏览器中都相同。

注意:您也可以尝试使用Key Event Tester(在上述站点上提供)来了解此概念。


1

释放按键时,无论按下键多长时间,KEYUP只会被捕获一次,因此,如果您只希望捕获一次按键,则KEYUP是适合捕获的事件。


KeyPress对于从输入生成的每个字符都会触发该事件,这是响应物理按键以及字符是自动重复功能的结果。键盘输入的工作方式记录了此行为。
IInspectable '18

你是对的。我将更新我的答案。正确的答案是使用KEYUP,它将在释放一个或多个按键时触发一次。
Michael Haephrati

虽然不再错误,但仍然无法回答所提出的问题。这没有用。
IInspectable '18年

0

最简单的解释:

我按住“ d”键一秒钟,然后放开。

dddddd

keydown事件发生在屏幕上第一个d之前发生一次,keypress事件发生了6次,而keyup事件发生在屏幕上最后一个d之后发生。


该死的,读错了问题,把它弄到我的脑海里,他的意思是javascript
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.