Was ist der Unterschied zwischen KeyDown und KeyPress in .NET?

185

Was ist der Unterschied zwischen KeyDownund KeyPressEreignissen in .net?

Josh Kodroff
quelle

Antworten:

307

Es gibt anscheinend viele Missverständnisse darüber!

Der einzige praktische Unterschied zwischen KeyDownund KeyPressbesteht darin, dass KeyPressdas aus einem Tastendruck resultierende Zeichen weitergeleitet wird und nur aufgerufen wird, wenn es eines gibt.

Mit anderen Worten, wenn Sie Aauf Ihrer Tastatur drücken , erhalten Sie diese Abfolge von Ereignissen:

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

Wenn Sie jedoch Shift+ drücken A, erhalten Sie:

  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

Wenn Sie die Tasten eine Weile gedrückt halten, erhalten Sie Folgendes:

  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

Beachten Sie, dass KeyPresstritt dazwischen KeyDown und KeyUp, nicht nach dem KeyUp, wie viele der anderen Antworten haben erklärt, dass KeyPressnicht aufgerufen wird , wenn ein Zeichen nicht erzeugt wird, und dass KeyDownwiederholt wird , während die Taste gedrückt gehalten wird , auch im Gegensatz zu vielen der anderen Antworten .

Beispiele für Schlüssel, die nicht direkt zu Aufrufen führen KeyPress:

  • Shift, Ctrl,Alt
  • F1 durch F12
  • Pfeiltasten

Beispiele für Schlüssel, die zu Aufrufen führen KeyPress:

  • Adurch Z, 0durch 9usw.
  • Spacebar
  • Tab (KeyChar = '\ t', ASCII 9)
  • Enter (KeyChar = '\ r', ASCII 13)
  • Esc (KeyChar = '\ x1b', ASCII 27)
  • Backspace (KeyChar = '\ b', ASCII 8)

Für die Neugierigen KeyDownkorreliert grob mit WM_KEYDOWN, KeyPresszu WM_CHARund KeyUpzu WM_KEYUP. WM_KEYDOWN kann als weniger als die Anzahl der Schlüsselwiederholungen bezeichnet werden, sendet jedoch eine Wiederholungsanzahl, mit der WinForms nach IIRC genau einen KeyDown pro Wiederholung generiert.

P Papa
quelle
2
Hervorragende Erklärung, danke, eine Einschränkung: Escape löst KeyPress auf Chrome nicht aus (bei den anderen nicht sicher).
Barney
3
@BarnabasSzabolcs: Chrome läuft .NET?
P Daddy
@PDaddy ups, ich habe übersehen, ich dachte, es wäre Javascript: D, aber mit etwas seltsamem Stil: P Trotzdem scheinen die Regeln ziemlich ähnlich zu sein: DD ... komischerweise hat mir diese Antwort trotzdem sehr geholfen.
Barney
@ PDaddy Ich weiß, dass mindestens Tab nicht standardmäßig KeyDown oder KeyUp auslöst
PsychoData
@PsychoData: Das liegt daran, dass die Tabulatortaste den Fokus ändert und daher nicht als Eingabe verarbeitet wird. Wenn Sie überschreiben ProcessDialogKeyund false zurückgeben, wenn keyDatais Keys.Taboder ist Keys.Shift | Keys.Tab, wird die Tabulatortaste in der Taste (On) angezeigt (Down | Press | Up).
P Daddy
73

Das KeyPress-Ereignis wird nicht durch Nichtzeichentasten ausgelöst. Die Nicht-Zeichen-Schlüssel lösen jedoch die Ereignisse KeyDown und KeyUp aus.

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

Jon spricht
quelle
17
Die meisten anderen Antworten sind auf die eine oder andere Weise falsch, aber diese kommt der Realität am nächsten. KeyPress wird nur für Zeichentasten ausgelöst und entspricht den Einstellungen für Verzögerungen / Wiederholungen beim Eingeben der Tastatur. Die tatsächliche Abfolge der Ereignisse ist: 1) KeyDown 2) für die Zeichentaste KeyPress einmal oder mehrmals (abhängig von den Systemeinstellungen und wie lange die Taste gedrückt gehalten wird) 3) KeyUp
Filip Navara
Ich habe nicht den Repräsentanten, aber könnte jemand ein Wiki kaputt machen und den Inhalt des obigen Kommentars und die akzeptierte Antwort kombinieren?
Josh Kodroff
11
Der Kommentar von Filip Navara ist nicht ganz richtig. Wenn eine Taste gedrückt gehalten wird, erhalten Sie KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown wird für jede Wiederholung aufgerufen.
P Daddy
9

KeyPress wird nur von druckbaren Zeichen ausgelöst und wird nach dem KeyDown-Ereignis ausgelöst. Abhängig von den Einstellungen für die Schreibverzögerung können mehrere KeyDown- und KeyPress-Ereignisse, jedoch nur ein KeyUp-Ereignis auftreten.

KeyDown
KeyPress
KeyUp

stevehipwell
quelle
Du bist nah dran, aber wegen der Sequenz.
P Daddy
@P Daddy - Ich habe es korrigiert, hätte es überprüfen sollen, bevor ich aus dem Speicher gehe.
Stevehipwell
@ Stevo3000, fyi: Nicht druckbare Unicode-Zeichen lösen auch KeyPress-Ereignisse aus. Ich habe eine App, die Daten liest, die von einem Barcodeleser in ein Textfeld eingefügt wurden, und der Leser enthält nicht druckbare Unicode-Zeichen.
Jeff LaFay
@jlafay - Nicht gemäß MSDN Das KeyPress-Ereignis wird nicht durch Nicht-Zeichen-Schlüssel ausgelöst. Die Nicht-Zeichen-Schlüssel lösen jedoch die Ereignisse KeyDown und KeyUp aus.
Stevehipwell
@ Stevo3000, ich bin nicht sicher, wie der Barcode-Scanner Text in ein Textfeld eingibt, aber die KeyPress wird für Sonderzeichen ausgelöst, die er sendet. Der Wert beginnt mit einem nicht druckbaren Zeichen und endet mit einem nicht druckbaren Zeichen. Ich bin mir also nicht sicher, wie es feuert, wenn das stimmt. Vielleicht schaue ich mir die .Net-Assembly an, die die Ereignisse mit IL Spy enthält, um einen besseren Überblick über die tatsächlich erkannten Ereignisse zu erhalten.
Jeff LaFay
5

KeyPress ist eine höhere Abstraktionsebene als KeyDown (und KeyUp). KeyDown und KeyUp sind hardwarebezogen: die tatsächliche Aktion einer Taste auf der Tastatur. KeyPress ist mehr "Ich habe ein Zeichen von der Tastatur erhalten".

Jeff Hornby
quelle
4

Von MSDN:

Wichtige Ereignisse treten in der folgenden Reihenfolge auf:

  1. Taste nach unten

  2. Tastendruck

  3. KeyUp

Darüber hinaus können Sie mit KeyPress die Aktion als " behandelt " deklarieren , um zu verhindern, dass sie etwas unternimmt.

Jon B.
quelle
Zu Ihrer Information, KeyDown und KeyUp haben auch eine Handled-Eigenschaft, die Sie festlegen können, damit keine Verbindung zwischen KeyPress und den anderen Schlüsselereignissen besteht.
Jeff LaFay
FWIW Obwohl KeyUp wie KeyDown einen KeyEventArgs-Parameter erhält, ist seine HandledEigenschaft für KeyUp nicht funktionsfähig ( SuppressKeyPressist auch nicht funktionsfähig).
JonP
3

Keydown drückt die Taste, ohne sie loszulassen. Keypress ist ein vollständiger Druck- und Freigabezyklus.

Anders ausgedrückt: KeyDown + KeyUp = Tastendruck

Rob Cowell
quelle
3
Laut MSDN lautet die Ereignissequenz KeyDown, KeyPress, KeyUp ( msdn.microsoft.com/en-us/library/… )
Nathan Koop
@RobCowell Wie jlafay betonte, ist KeyPress überhaupt nicht von KeyDown oder KeyUp abhängig.
PsychoData
1

Vom Blogging-Entwickler :

Um den Unterschied zwischen Tastendruck und Tastendruck zu verstehen, ist es hilfreich, den Unterschied zwischen einem "Zeichen" und einer "Taste" zu verstehen . Eine "Taste" ist eine physische Taste auf der Tastatur des Computers, während ein "Zeichen" ein Symbol ist, das durch Drücken einer Taste eingegeben wird. Theoretisch stellen die Keydown- und Keyup-Ereignisse Tasten dar , die gedrückt oder losgelassen werden, während das Tastendruckereignis ein eingegebenes Zeichen darstellt . Die Implementierung der Theorie ist nicht in allen Browsern gleich.

Hinweis: Sie können auch den Key Event Tester (verfügbar auf der oben genannten Website) ausprobieren, um dieses Konzept zu verstehen.

Abdul Latheef Mohamed
quelle
1

KEYUP wird nur einmal erfasst, wenn die Taste gedrückt wird, unabhängig davon, wie lange die Taste gedrückt gehalten wird. Wenn Sie also einen solchen Druck nur einmal erfassen möchten, ist KEYUP das geeignete Ereignis zum Erfassen.

Michael Haephrati
quelle
Das KeyPressEreignis wird für jedes aus der Eingabe erzeugte Zeichen ausgelöst, sowohl als Reaktion auf physische Tastendrücke als auch wenn das Zeichen das Ergebnis der automatischen Wiederholungsfunktion ist. Funktionsweise der Tastatureingabe dokumentiert dieses Verhalten.
Unsichtbarer
Du hast recht. Ich werde meine Antwort aktualisieren. Die richtige Antwort ist die Verwendung von KEYUP, das einmal ausgelöst wird, wenn ein oder mehrere Schlüsseltreffer ausgelöst werden.
Michael Haephrati
Es ist zwar nicht mehr falsch, beantwortet aber immer noch nicht die gestellte Frage. Das ist nicht sinnvoll.
Unsichtbarer
0

Einfachste Erklärung:

Ich hielt die 'd'-Taste eine Sekunde lang gedrückt und ließ sie dann los.

dddddd

Das Keydown-Ereignis ereignete sich einmal, bevor das erste d auf dem Bildschirm angezeigt wurde, das Tastendruckereignis 6 Mal und das Keyup-Ereignis, nachdem das letzte d auf dem Bildschirm angezeigt wurde.


quelle
Verdammt, habe die Frage falsch verstanden und in meinen Kopf bekommen. Er meinte Javascript