В чем разница между KeyDown и KeyPress в .NET?


Ответы:


308

По-видимому, есть много недоразумений по этому поводу!

Единственное практическое различие между KeyDownи KeyPressзаключается в том, что он KeyPressпередает символ, полученный в результате нажатия клавиши, и вызывается только при его наличии.

Другими словами, если вы нажмете 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, Modifiers = Keys.Shift
  2. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modifiers = 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, Modifiers = Keys.Shift
  2. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  3. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  4. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  5. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  6. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modifiers = Keys.Shift
  7. KeyPress: KeyChar = 'A'
  8. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modifiers = Keys.Shift
  9. KeyPress: KeyChar = 'A'
  10. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modifiers = Keys.Shift
  11. KeyPress: KeyChar = 'A'
  12. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modifiers = Keys.Shift
  13. KeyPress: KeyChar = 'A'
  14. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modifiers = Keys.Shift
  15. KeyPress: KeyChar = 'A'
  16. KeyUp: KeyCode = Keys.A
  17. KeyUp: KeyCode = Keys.ShiftKey

Обратите внимание , что KeyPressпроисходит между ними KeyDown и KeyUp, не после KeyUp, как многие другие ответы заявили, что KeyPressне вызывается , когда персонаж не генерируется, и что KeyDownповторяется , пока клавиша удерживается в нажатом положении , а также в отличие от многих других ответов ,

Примеры ключей, которые не приводят непосредственно к вызовам KeyPress:

  • Shift, Ctrl,Alt
  • F1 через F12
  • Клавиши со стрелками

Примеры ключей , которые делают результат в вызовах KeyPress:

  • Aчерез Z, 0через 9и т.д.
  • Spacebar
  • Tab (KeyChar = '\ t', ASCII 9)
  • Enter (KeyChar = '\ r', ASCII 13)
  • Esc (KeyChar = '\ x1b', ASCII 27)
  • Backspace (KeyChar = '\ b', ASCII 8)

Для любопытных, KeyDownгрубо говоря, соотносится с WM_KEYDOWN, KeyPressчтобы WM_CHARи KeyUpчтобы WM_KEYUP. WM_KEYDOWN может вызываться меньше, чем количество повторений клавиш, но отправляет счетчик повторений, который, IIRC, WinForms использует для генерации ровно одного KeyDown за повтор.


2
Отличное объяснение, спасибо за одно предостережение, Escape не запускает KeyPress в Chrome (не уверен насчет других).
Барни

3
@BarnabasSzabolcs: Chrome работает .NET?
P Daddy

@Paddy ups, я упустил из виду, я думал, что это был javascript: D, но с немного странным стилем: P, тем не менее, похоже, что правила довольно похожи: DD ... как ни странно, этот ответ мне все равно очень помог .. ура :)
Барни

@PDaddy Я знаю, что по крайней мере Tab не запускает KeyDown или KeyUp по умолчанию
PsychoData

@PsychoData: Это потому, что клавиша Tab меняет фокус, поэтому она не обрабатывается как ввод. Если вы переопределите ProcessDialogKeyи вернете false, когда keyDataесть Keys.Tabили Keys.Shift | Keys.Tab, тогда вы увидите клавишу Tab в клавише (Вкл.) (Вниз | Нажмите | Вверх).
P Daddy

73

Событие KeyPress не вызывается не символьными клавишами; однако нехарактерные ключи вызывают события KeyDown и KeyUp.

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx


17
Большинство других ответов так или иначе неверны, но этот наиболее близок к реальности. KeyPress вызывается только для символьных клавиш и подчиняется настройке задержки / повторения набора с клавиатуры. Фактическая последовательность событий: 1) KeyDown 2) для символьной клавиши KeyPress один или несколько раз (в зависимости от настроек системы и длительности удержания клавиши) 3) KeyUp
Filip Navara

У меня нет представителя, чтобы сделать это, но может ли кто-нибудь взломать вики и объединить содержание вышеуказанного комментария и принятый ответ?
Джош Кодрофф

11
Комментарий Филипа Навары не совсем корректен. Если удерживать клавишу нажатой, вы получите KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown вызывается для каждого повтора.
P Daddy

9

KeyPress запускается только для печатных символов и после события KeyDown. В зависимости от настроек задержки ввода может быть несколько событий KeyDown и KeyPress, но только одно событие KeyUp.

KeyDown
KeyPress
KeyUp


Вы близки, но по поводу последовательности.
P Daddy

@P Папа - я исправил это, должен был дважды проверить прежде, чем уйти из памяти.
Stevehipwell

@ Stevo3000, fyi: непечатные символы Юникода также будут запускать события KeyPress. У меня есть приложение, которое считывает данные, вставленные устройством для считывания штрих-кода в текстовое поле, и оно содержит непечатаемые символы Юникода.
Джефф ЛаФай

@jlafay - не соответствует MSDN Событие KeyPress не вызывается не символьными ключами; однако нехарактерные ключи вызывают события KeyDown и KeyUp.
Stevehipwell

@ Stevo3000, я не уверен, как сканер штрих-кода вводит текст в текстовое поле, но KeyPress срабатывает для специальных символов, которые он отправляет. Значение начинается с непечатаемого символа и заканчивается непечатаемым символом. Так что я не уверен, как это стреляет, если это правда. Может быть, я взгляну на сборку .Net, которая содержит события с IL Spy, чтобы лучше взглянуть на то, что на самом деле обнаружено.
Джефф ЛаФай,

5

KeyPress - более высокий уровень абстракции, чем KeyDown (и KeyUp). KeyDown и KeyUp связаны с аппаратным обеспечением: фактическое действие клавиши на клавиатуре. KeyPress больше "Я получил символ с клавиатуры".


4

Из MSDN:

Ключевые события происходят в следующем порядке:

  1. KeyDown

  2. Нажатие клавиши

  3. KeyUp

Кроме того, KeyPress дает вам возможность объявить действие как « обработанное », чтобы оно ничего не делало.


FYI, KeyDown и KeyUp также имеют свойство Handled, которое вы можете установить так, чтобы оно не было промежуточным между KeyPress и другими событиями клавиш.
Джефф ЛаФай

FWIW, хотя KeyUp, как и KeyDown, получает параметр KeyEventArgs, его Handledсвойство не работает для KeyUp ( SuppressKeyPressтакже не работает).
JonP


3

Keydown нажимает клавишу, не отпуская ее, нажатие клавиши - это полный цикл пресс-релизов.

Другими словами, KeyDown + KeyUp = Keypress


3
согласно MSDN, последовательность событий - KeyDown, KeyPress, KeyUp ( msdn.microsoft.com/en-us/library/… )
Натан Куп

@RobCowell Также, как указал jlafay, KeyPress вовсе не зависит от KeyDown или KeyUp.
PsychoData

1

От разработчика блогов :

Чтобы понять разницу между нажатием клавиши и нажатием клавиши, полезно понять разницу между «символом» и «ключом» . «Ключ» является физической кнопкой на клавиатуре компьютера в то время как «символ» является символ набран нажатием кнопки. Теоретически, события нажатия клавиш и нажатия клавиш представляют собой нажатие или отпускание клавиш , в то время как событие нажатия клавиш представляет вводимый символ . Реализация теории не одинакова во всех браузерах.

Примечание: Вы также можете попробовать Key Event Tester (доступен на вышеупомянутом сайте), чтобы понять эту концепцию.


1

KEYUP будет захвачен только один раз, после отпускания нажатой клавиши, независимо от того, как долго будет удерживаться клавиша, поэтому, если вы хотите захватить такое нажатие только один раз, KEYUP является подходящим событием для захвата.


KeyPressСобытие возникает для каждого символа , генерируемого от входа, как в ответ на прессы физических ключевыми, а также , когда персонаж является результатом функции автоповтора. Как работает ввод с клавиатуры, документирует это поведение.
Инспектируемое

Ты прав. Я обновлю свой ответ. Правильный ответ - использовать KEYUP, который будет запущен один раз при отпускании одного или нескольких нажатий клавиш.
Майкл Хефрати

Хотя он больше не ошибается, он все равно не отвечает на заданный вопрос. Это не полезно.
IInspectable

0

Самое простое объяснение:

Я удерживал клавишу «d» на секунду, а затем отпустил.

DDDDDD

Событие нажатия клавиши произошло один раз до появления первого d на экране, событие нажатия клавиши произошло 6 раз, а событие keyup произошло после появления последнего d на экране.


блин, неправильно прочитал вопрос и получил его в голову, он имел в виду javascript
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.