Quelle est la différence entre KeyDown et KeyPress dans .NET?

185

Quelle est la différence entre les événements KeyDownet KeyPressdans .net?

Josh Kodroff
la source

Réponses:

308

Il y a apparemment beaucoup de malentendus à ce sujet!

La seule différence pratique entre KeyDownet KeyPressest que KeyPressrelaie le caractère résultant d'une pression sur une touche et n'est appelé que s'il y en a une.

En d'autres termes, si vous appuyez Asur votre clavier, vous obtiendrez cette séquence d'événements:

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

Mais si vous appuyez sur Shift+ A, vous obtiendrez:

  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

Si vous maintenez les touches enfoncées pendant un moment, vous obtiendrez quelque chose comme:

  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

Remarquez qui KeyPressse produit entre KeyDown et KeyUp, pas après KeyUp, comme beaucoup d'autres réponses l'ont indiqué, qui KeyPressn'est pas appelé lorsqu'un personnage n'est pas généré, et qui KeyDownest répété pendant que la touche est maintenue enfoncée, également contrairement à de nombreuses autres réponses .

Exemples de clés qui ne donnent pas directement lieu à des appels à KeyPress:

  • Shift, Ctrl,Alt
  • F1 à travers F12
  • Touches directionnelles

Des exemples de touches qui font suite à des appels à KeyPress:

  • Aà travers Z, à 0travers 9, etc.
  • Spacebar
  • Tab (KeyChar = '\ t', ASCII 9)
  • Enter (KeyChar = '\ r', ASCII 13)
  • Esc (KeyChar = '\ x1b', ASCII 27)
  • Backspace (KeyChar = '\ b', ASCII 8)

Pour les curieux, KeyDowncorrespond à peu près à WM_KEYDOWN, KeyPressà WM_CHARet KeyUpà WM_KEYUP. WM_KEYDOWN peut être appelé moins que le nombre de répétitions de touches, mais il envoie un nombre de répétitions, qui, IIRC, WinForms utilise pour générer exactement un KeyDown par répétition.

Papa
la source
2
Excellente explication, merci, une mise en garde cependant, Escape ne déclenche pas KeyPress sur Chrome (pas sûr des autres).
Barney
3
@BarnabasSzabolcs: Chrome exécute .NET?
P Daddy
@PDaddy ups, j'ai négligé, j'ai pensé que c'était javascript: D mais avec un style un peu bizarre: P quand même, il semble que les règles soient assez similaires: DD ... curieusement cette réponse m'a beaucoup aidé de toute façon .. . cheers :)
Barney
@PDaddy Je sais qu'au moins Tab ne déclenche pas KeyDown ou KeyUp par défaut
PsychoData
@PsychoData: C'est parce que la touche Tab change de focus, donc elle n'est pas traitée comme entrée. Si vous remplacez ProcessDialogKeyet renvoyez false lorsque keyDataest Keys.Tabou Keys.Shift | Keys.Tab, vous verrez la touche Tab dans la touche (Marche) (Bas | Appuyez sur | Haut).
P Daddy
73

L'événement KeyPress n'est pas déclenché par des clés sans caractère; cependant, les clés sans caractère déclenchent les événements KeyDown et KeyUp.

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

Jon Spokes
la source
17
La plupart des autres réponses sont fausses d'une manière ou d'une autre, mais celle-ci se rapproche le plus de la réalité. KeyPress est déclenché uniquement pour les touches de caractères et il obéit au réglage des retards / répétition de frappe au clavier. La séquence actuelle des événements est la suivante: 1) KeyDown 2) pour la touche de caractère KeyPress une ou plusieurs fois (selon les paramètres du système et la durée pendant laquelle la touche est maintenue) 3) KeyUp
Filip Navara
Je n'ai pas le représentant pour le faire, mais quelqu'un pourrait-il casser un wiki et combiner le contenu du commentaire ci-dessus et la réponse acceptée?
Josh Kodroff le
11
Le commentaire de Filip Navara n'est pas entièrement correct. Si une touche est maintenue enfoncée, vous obtiendrez KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown est appelé à chaque répétition.
P Daddy le
9

KeyPress n'est déclenché que par des caractères imprimables et est déclenché après l'événement KeyDown. En fonction des paramètres de délai de saisie, il peut y avoir plusieurs événements KeyDown et KeyPress, mais un seul événement KeyUp.

KeyDown
KeyPress
KeyUp

Stevehipwell
la source
Vous êtes proche, mais hors de la séquence.
P Daddy le
@P Daddy - Je l'ai corrigé, j'aurais dû vérifier avant de partir de mémoire.
stevehipwell le
@ Stevo3000, fyi: les caractères Unicode non imprimables déclencheront également les événements KeyPress. J'ai une application qui lit les données insérées par un lecteur de code-barres dans une zone de texte et le lecteur comprend des caractères Unicode non imprimables.
Jeff LaFay
@jlafay - Pas selon MSDN L'événement KeyPress n'est pas déclenché par des clés sans caractère; cependant, les clés sans caractère déclenchent les événements KeyDown et KeyUp.
stevehipwell
@ Stevo3000, je ne suis pas sûr de la façon dont le lecteur de codes-barres saisit le texte dans une zone de texte, mais KeyPress se déclenche pour les caractères spéciaux qu'il envoie. La valeur commence par un caractère non imprimable et se termine par un caractère non imprimable. Donc je ne sais pas comment ça tire si c'est vrai. Peut-être que je vais jeter un œil à l'assembly .Net qui contient les événements avec IL Spy pour avoir un meilleur aperçu de ce qui est réellement détecté.
Jeff LaFay
5

KeyPress est un niveau d'abstraction plus élevé que KeyDown (et KeyUp). KeyDown et KeyUp sont liés au matériel: l'action réelle d'une touche sur le clavier. KeyPress est plus "j'ai reçu un caractère du clavier".

Jeff Hornby
la source
4

Depuis MSDN:

Les événements clés se produisent dans l'ordre suivant:

  1. Touche Bas

  2. Appuyez sur la touche

  3. KeyUp

De plus, KeyPress vous donne une chance de déclarer l'action comme " gérée " pour l'empêcher de faire quoi que ce soit.

Jon B
la source
FYI, KeyDown et KeyUp ont également une propriété Handled que vous pouvez définir de manière à ne pas être entre KeyPress et les autres événements clés.
Jeff LaFay
FWIW bien que KeyUp, comme KeyDown, obtienne un paramètre KeyEventArgs, sa Handledpropriété est inopérante pour KeyUp ( SuppressKeyPressest également inopérante).
JonP
3

Keydown appuie sur la touche sans la relâcher, Keypress est un cycle complet de pression et de relâchement.

En d'autres termes, KeyDown + KeyUp = Keypress

Rob Cowell
la source
3
selon MSDN, la séquence d'événements est KeyDown, KeyPress, KeyUp ( msdn.microsoft.com/en-us/library/… )
Nathan Koop
@RobCowell De plus, comme jlafay l'a souligné, KeyPress n'est pas du tout dépendant de KeyDown ou KeyUp.
PsychoData
1

Du développeur de blogs :

Afin de comprendre la différence entre la touche enfoncée et la pression d'une touche, il est utile de comprendre la différence entre un «caractère» et une «touche» . Une «touche» est un bouton physique sur le clavier de l'ordinateur tandis qu'un «caractère» est un symbole tapé en appuyant sur un bouton. En théorie, les événements keydown et keyup représentent des touches pressées ou relâchées, tandis que l'événement keypress représente un caractère tapé. La mise en œuvre de la théorie n'est pas la même dans tous les navigateurs.

Remarque: vous pouvez également essayer le Key Event Tester (disponible sur le site mentionné ci-dessus) pour comprendre ce concept.

Abdul Latheef Mohamed
la source
1

KEYUP ne sera capturé qu'une seule fois, lors du relâchement de la touche enfoncée, quelle que soit la durée pendant laquelle la touche sera maintenue enfoncée, donc si vous souhaitez capturer cette pression une seule fois, KEYUP est l'événement approprié à capturer.

Michael Haephrati
la source
L' KeyPressévénement est déclenché pour chaque caractère généré à partir de l'entrée, à la fois en réponse à des pressions de touches physiques et lorsque le caractère est le résultat de la fonction de répétition automatique. Le fonctionnement de la saisie au clavier documente ce comportement.
IInspectable
Vous avez raison. Je mettrai à jour ma réponse. La bonne réponse est d'utiliser KEYUP qui sera déclenché une fois, lors du relâchement d'un ou plusieurs touches.
Michael Haephrati
Bien que ce ne soit plus faux, il ne répond toujours pas à la question qui a été posée. Ce n'est pas utile.
IInspectable le
0

Explication la plus simple:

J'ai maintenu la touche «d» enfoncée pendant une seconde puis relâchée.

dddddd

l'événement keydown s'est produit une fois avant que le premier d n'apparaisse à l'écran, l'événement keypress s'est produit 6 fois et l'événement keyup s'est produit après que le dernier d est apparu à l'écran.


la source
putain, j'ai mal lu la question et je l'ai mis dans ma tête, il voulait dire javascript