77 votes

Différence entre l'événement KeyDown, l'événement KeyPress et l'événement KeyUp dans Visual Studio

Quelqu'un peut-il me dire quelle est la différence entre le KeyDown l'événement, le KeyPress et l'événement KeyUp événement ? J'ai vérifié le site msdn et il ne l'explique pas beaucoup.

Quelqu'un peut-il me dire en toute logique quand chacun de ces événements se produit ? Je pense que tous les événements ci-dessus se produisent lorsqu'une touche est pressée. Alors quelle est la différence exacte entre eux.

92voto

Cody Gray Points 102261

La documentation MSDN énonce assez clairement l'ordre dans lequel les trois événements se produisent :

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

  1. KeyDown
  2. KeyPress
  3. KeyUp

KeyDown est déclenché dès que l'utilisateur appuie sur une touche du clavier, alors qu'il la maintient enfoncée.

KeyPress est relevé pour caractère (contrairement à KeyDown et KeyUp, qui sont également levées pour les touches sans caractère) pendant que la touche est enfoncée. Il s'agit d'un événement de "niveau supérieur" par rapport à KeyDown ou KeyUp, et en tant que tel, des données différentes sont disponibles dans la fenêtre de l'événement. EventArgs .

KeyUp est soulevé après que l'utilisateur ait relâché une touche du clavier.

En règle générale, vous devez traiter le KeyUp dans votre application. Les actions ne doivent pas être lancées dans l'interface utilisateur avant que après l'utilisateur relâche la clé. Et comme KeyUp est un événement de niveau inférieur à KeyPress vous aurez toujours à portée de main de nombreuses informations sur la touche qui a été enfoncée, et cela fonctionnera même pour la gestion des touches sans caractère.


Ce qu'il faut savoir sur tous Cependant, la particularité de ces événements est qu'ils ne sont déclenchés que par le contrôle qui a le focus. Cela signifie que si un contrôle de bouton sur votre formulaire a actuellement le focus, aucun des événements clés pour votre contrôle de bouton ne sera déclenché. formulaire ne sera jamais levé. Cette situation est souvent déroutante pour les programmeurs novices en .NET. La meilleure façon de gérer ce problème est de remplacer la fonction ProcessCmdKey méthode :

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == (Keys.Control | Keys.A))
    {
        MessageBox.Show("You pressed Ctrl+A!");
    }
    return base.ProcessCmdKey(ref msg, keyData);
}

0 votes

Je me demande si cette information est facile à trouver. Il me semble que ce serait utile s'il existait un site avec un tableau montrant l'ordre d'apparition des événements pour chaque contrôle natif de Windows...

0 votes

Ou peut-être une sorte de site d'agrégation d'informations avec un format questions-réponses pour rendre ces informations facilement accessibles ? Aller à la documentation originale n'est pas toujours la solution idéale...

0 votes

@Clay Ils n'ont pas un tel tableau parce que l'ordre des événements/messages est (en général) susceptible de changer à tout moment. Il s'agit d'un détail d'implémentation du contrôle sous-jacent, vous ne pouvez donc pas vous fier à un ordre particulier pour les événements/messages. tous messages disponibles. Mais certains messages particuliers sont toujours envoyés dans un ordre particulier, simplement en raison de leur conception et de leur signification. Par exemple, ceux que j'ai mentionnés ici. La documentation de WinForms a une très bonne explication de ceci pour les événements liés aux touches, je pense.

73voto

Roy T. Points 3307
  • KeyDown : se produit lorsque la personne appuie sur une touche (lorsque le clavier détecte pour la première fois un doigt sur une touche, cela se produit lorsque la touche est enfoncée).

  • KeyPress : se produit lorsqu'une touche est enfoncée puis relâchée.

  • KeyUp : se produit lorsque la touche est relâchée

Vous avez raison de dire que tous ces événements se produisent lorsqu'une touche est enfoncée puis relâchée, dans l'ordre que j'ai décrit ci-dessus.

2 votes

Même si reggie n'a pas posé cette question, j'ai ajouté une réponse ci-dessous avec des réflexions sur l'utilisation de KeyDown par rapport à KeyUp.

9 votes

Le site KeyPress La description est fausse. KeyPress se produit tant que la touche est enfoncée, même si elle n'est jamais relâchée. Voir La réponse de Cody Gray .

0 votes

Et KeyPress ne se déclenche qu'une fois. KeyDown tire en continu si la touche est maintenue enfoncée.

8voto

Jim C Points 587

Voici un cas où vous ne voulez pas utiliser KeyUp :

Vous avez une boîte de liste et le fait d'appuyer sur la touche Entrée sur une ligne invoque une boîte de dialogue d'éditeur. Problème : si l'utilisateur appuie sur la touche Entrée sur le bouton OK de l'éditeur, un événement KeyUp(e.KeyCode=Enter) sera renvoyé à votre zone de liste, entraînant la réouverture de l'éditeur. Cela ne se produit pas si l'utilisateur appuie sur la barre d'espacement sur le bouton OK de l'éditeur ; dans ce cas, l'événement KeyUp(e.KeyCode=Space) est traité par l'éditeur avant qu'il ne se ferme.

Voici une heuristique de sélection que j'utilise :

If I'm handling the Enter key and I need to guard against a case like the one above
  then I use KeyDown    
Else if I'm handling key combinations (e.g. CTRL+C)
   then I favor* KeyDown (KeyUp can make these awkward)   
Else if I am allowing press & hold autorepeat
  then I use KeyDown    
Else 
  I use KeyUp

*Si l'action peut être effectuée dans un produit couramment utilisé, par exemple Microsoft Office, comme CTRL+A (pour "Sélectionner tout"), j'imite le comportement de Microsoft, car c'est ce à quoi les utilisateurs sont habitués.

0 votes

Des réflexions très utiles, Jim. Mais, est-ce que cela ne résulte pas en une expérience incohérente ? On pourrait dire que cela ne devrait pas se produire, car la boîte de dialogue ne devrait pas agir avant l'événement KeyUp. Jusqu'à présent, j'ai toujours utilisé KeyUp (pour la touche Entrée) pour être cohérent, mais je me suis heurté à votre problème d'état.

0 votes

Dans WPF, la "fuite" de la touche Entrée peut être évitée en la traitant par un événement de prévisualisation, n'est-ce pas ?

0 votes

Merci -- Je n'ai pas pu attraper "Alt-F4" dans KeyUp j'ai dû utiliser KeyDown.

5voto

marsze Points 751

En plus des autres réponses :

Lorsque vous essayez de déterminer lequel de ces événements vous devez associer à votre action, gardez à l'esprit que l'élément de base de l'action est l'action. KeyDown l'événement sera déclenché multiple pendant que la touche est maintenue enfoncée. Parfois vous voulez ce comportement, parfois non. Sur cette base, je suggère l'utilisation suivante (basée sur mon expérience) :

(Ordre dans lequel les événements sont déclenchés)

KeyDown

Cela se produit : Lorsque la touche est enfoncée et lorsqu'elle est maintenue enfoncée
Utilisation : Effectuer une action immédiatement en appuyant sur le bouton ou même plusieurs fois en le maintenant enfoncé.
Exemple : Déplacement du curseur avec les touches fléchées

.

KeyPress

Cela se produit : Une touche de caractère est pressée (événement de niveau supérieur)
Utilisation : Tout ce qui concerne la dactylographie
Exemple : Gérer l'entrée de la boîte de texte

.

KeyUp

Cela se produit : La clé est libérée
Utilisation : Effectuer une action critique qui ne doit se produire qu'une seule fois par frappe.
Exemple : Écrire des données dans un fichier

2voto

Christo Points 2367

KeyDown puis KeyPress puis KeyUp est l'ordre que je trouve.

Habituellement, vous voulez accrocher KeyDown lorsqu'il s'agit d'une application où un utilisateur maintient une touche enfoncée pour une entrée multi-mode avec modification du mode de la touche de commande, comme dans une opération de type shift-clic. KeyPress est pour une logique simple de saisie de touches -- juste pour obtenir les frappes de touches. KeyUp est accroché pour mettre en place une logique qui s'exécute après que quelque chose d'autre ait été traité. KeyPress J'aimerais modifier le contenu d'une boîte d'édition de texte après qu'elle ait été ouverte. KeyPress la logique a pris effet. Franchement, je n'utilise pas KeyUp mais c'est parfois le seul moyen d'obtenir un message après que quelque chose d'autre ait été traité. KeyPress et vous devez vérifier / réparer ce qui s'est passé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X