Jaka jest różnica między KeyDown i KeyPress w .NET?


185

Jaka jest różnica między wydarzeniami KeyDowna ?KeyPress.net

Odpowiedzi:


308

Widocznie istnieje wiele nieporozumień!

Jedyną praktyczną różnicą między KeyDowni KeyPressjest to, że KeyPressprzekazuje postać wynikającą z naciśnięcia klawisza i jest wywoływana tylko wtedy, gdy istnieje.

Innymi słowy, jeśli naciśniesz Ana klawiaturze, otrzymasz następującą sekwencję zdarzeń:

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

Ale jeśli naciśniesz Shift+ A, otrzymasz:

  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

Jeśli przytrzymasz klawisze przez chwilę, otrzymasz coś takiego:

  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

Zauważ, że KeyPresspojawia się pomiędzy KeyDown i KeyUp, nie po tym KeyUp, jak w wielu innych odpowiedzi stwierdzili, że KeyPressnie jest wywoływana, gdy postać nie jest generowany, a KeyDownpowtarza się, gdy przycisk jest wciśnięty, także w przeciwieństwie do wielu innych odpowiedzi .

Przykłady kluczy, które nie powodują bezpośrednio wywołań KeyPress:

  • Shift, Ctrl,Alt
  • F1 przez F12
  • Klawisze strzałek

Przykłady kluczy, które powodują wywołania KeyPress:

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

Dla ciekawskich, z KeyDowngrubsza koreluje z WM_KEYDOWN, KeyPressdo WM_CHARi KeyUpdo WM_KEYUP. WM_KEYDOWN można nazwać mniejszą niż liczba powtórzeń klucza, ale wysyła on liczbę powtórzeń, którą IIRC, WinForms używa do wygenerowania dokładnie jednego KeyDown na powtórzenie.


2
Doskonałe wyjaśnienie, dzięki, jedno zastrzeżenie, Escape nie uruchamia KeyPress w Chrome (nie jestem pewien co do pozostałych).
Barney

3
@BarnabasSzabolcs: Chrome działa na platformie .NET?
P Daddy,

@PDaddy ups, przeoczyłem, myślałem, że to javascript: D, ale z nieco dziwnym stylem: P, jednak wydaje się, że zasady są bardzo podobne: DD ... co zabawne, ta odpowiedź i tak bardzo mi pomogła .. , na zdrowie :)
Barney

@PDaddy Wiem, że przynajmniej Tab domyślnie nie uruchamia KeyDown ani KeyUp
PsychoData

@PsychoData: To dlatego, że klawisz Tab zmienia fokus, więc nie jest przetwarzany jako dane wejściowe. Jeśli zastąpisz ProcessDialogKeyi zwrócisz wartość false, gdy keyDatajest Keys.Tablub Keys.Shift | Keys.Tab, zobaczysz klawisz Tab w klawiszu (Wł.) (W dół | Naciśnij | W górę).
P Daddy,

73

Zdarzenie KeyPress nie jest wywoływane przez klucze inne niż znaki; jednak klucze nieznakowe wywołują zdarzenia KeyDown i KeyUp.

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


17
Większość pozostałych odpowiedzi jest błędna w ten czy inny sposób, ale ta jest najbliższa rzeczywistości. Klawiatura jest podnoszona tylko dla klawiszy znakowych i jest zgodna z ustawieniami opóźnień / powtarzania pisania na klawiaturze. Rzeczywista sekwencja zdarzeń to: 1) KeyDown 2) dla klawisza postaci Klawisz Naciśnij jeden lub więcej razy (w zależności od ustawień systemowych i czasu przytrzymania klawisza) 3) KeyUp
Filip Navara

Nie mam do tego przedstawiciela, ale czy ktoś mógłby złamać wiki i połączyć treść powyższego komentarza z zaakceptowaną odpowiedzią?
Josh Kodroff

11
Komentarz Filipa Navary nie jest całkowicie poprawny. Jeśli klawisz zostanie przytrzymany, otrzymasz KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown jest wywoływany dla każdego powtórzenia.
P Daddy,

9

KeyPress jest uruchamiany tylko przez znaki do wydrukowania i jest uruchamiany po zdarzeniu KeyDown. W zależności od ustawień opóźnienia pisania może istnieć wiele zdarzeń KeyDown i KeyPress, ale tylko jedno zdarzenie KeyUp.

KeyDown
KeyPress
KeyUp


Jesteś blisko, ale nie rozumiesz sekwencji.
P Daddy,

@P Tato - Poprawiłem to, powinienem dwukrotnie sprawdzić przed wyjściem z pamięci.
stevehipwell

@ Stevo3000, fyi: niedrukowalne znaki Unicode będą również uruchamiać zdarzenia KeyPress. Mam aplikację, która odczytuje dane wstawione przez czytnik kodów kreskowych do pola tekstowego, a czytnik zawiera niedrukowalne znaki Unicode.
Jeff LaFay,

@jlafay - Nie zgodnie z MSDN Zdarzenie KeyPress nie jest wywoływane przez klucze inne niż znaki; jednak klucze nieznakowe wywołują zdarzenia KeyDown i KeyUp.
stevehipwell

@ Stevo3000, nie jestem pewien, jak skaner kodów kreskowych wprowadza tekst do pola tekstowego, ale KeyPress odpala dla znaków specjalnych, które wysyła. Wartość zaczyna się od znaku niedrukowalnego i kończy się znakiem niedrukowalnym. Więc nie jestem pewien, jak się strzela, jeśli to prawda. Może przyjrzę się zespołowi .Net, który zawiera zdarzenia z IL Spy, aby lepiej zobaczyć, co faktycznie zostało wykryte.
Jeff LaFay,

5

KeyPress to wyższy poziom abstrakcji niż KeyDown (i KeyUp). KeyDown i KeyUp są związane ze sprzętem: faktyczne działanie klawisza na klawiaturze. KeyPress to więcej: „Otrzymałem znak z klawiatury”.


4

Z MSDN:

Kluczowe zdarzenia występują w następującej kolejności:

  1. KeyDown

  2. KeyPress

  3. KeyUp

Co więcej, KeyPress daje Ci możliwość zadeklarowania akcji jako „ obsłużonej ”, aby zapobiec jej wykonaniu.


Informacje FYI, KeyDown i KeyUp również mają właściwość Handled, którą można ustawić, aby nie była pomiędzy KeyPress a innymi kluczowymi zdarzeniami.
Jeff LaFay

FWIW, chociaż KeyUp, podobnie jak KeyDown, pobiera parametr KeyEventArgs, jego Handledwłaściwość nie działa dla KeyUp ( SuppressKeyPressrównież nie działa).
JonP,



1

Od twórcy blogów :

Aby zrozumieć różnicę między naciśnięciem klawisza a naciśnięciem klawisza, warto zrozumieć różnicę między „postacią” a „klawiszem” . „Klucz” to fizyczny przycisk na klawiaturze komputera, podczas gdy „charakter” to symbol wpisany przez naciśnięcie przycisku. W teorii, keyDown i keyUp wydarzenia stanowią klucze zostanie naciśnięty lub zwolniony, natomiast naciśnięcie klawisza zdarzeń reprezentuje postać jest wpisany. Implementacja teorii nie jest taka sama we wszystkich przeglądarkach.

Uwaga: możesz również wypróbować Key Event Tester (dostępny na wyżej wymienionej stronie), aby zrozumieć tę koncepcję.


1

KEYUP zostanie przechwycony tylko raz, po zwolnieniu naciśniętego klawisza, niezależnie od tego, jak długo będzie przytrzymany klawisz, więc jeśli chcesz uchwycić takie naciśnięcie tylko raz, KEYUP jest odpowiednim wydarzeniem do przechwycenia.


KeyPressZdarzenie jest wywoływane dla każdego znaku wygenerowanego z wejścia, zarówno w odpowiedzi na naciśnięć klawiszy fizycznych, jak również wtedy, gdy postać jest wynikiem funkcji autorepeat. Jak działa klawiatura, dokumentuje to zachowanie.
Widoczny

Masz rację. Zaktualizuję swoją odpowiedź. Prawidłowa odpowiedź to użycie KEYUP, która zostanie uruchomiona raz, po zwolnieniu jednego lub więcej kluczowych uderzeń.
Michael Haephrati

Chociaż nie jest już w błędzie, nadal nie odpowiada na zadane pytanie. To nie jest przydatne.
Widoczny

0

Najłatwiejsze wyjaśnienie:

Przytrzymałem klawisz „d” przez sekundę, a następnie zwolniłem.

dddddd

zdarzenie keydown miało miejsce raz przed pojawieniem się pierwszego d na ekranie, zdarzenie keypress nastąpiło 6 razy, a zdarzenie keupown nastąpiło po ostatnim d na ekranie.


cholera, źle przeczytałem pytanie i włożyłem sobie do głowy, miał na myśli javascript
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.