Je travaille depuis un certain temps sur mon projet Windows Forms et j’ai décidé d’expérimenter les raccourcis clavier. Après un peu de lecture, j’ai pensé que je devais écrire un gestionnaire d’événement et le lier à l’événement KeyDown du formulaire:
private void Form1_KeyDown(object sender, KeyEventArgs e) { if (e.Control && e.Alt && e.KeyCode == Keys.O) { MessageBox.Show("Ctrl+Alt+O: magic!"); } }
Je l’ai fait comme le bon moyen d’ouvrir le panneau Propriétés du concepteur Visual Studio, puis de double-cliquer sur l’événement KeyDown de mon formulaire pour générer le Form1_KeyDown
événements Form1_KeyDown
. Mais en testant mon application, le formulaire ne répond pas du tout au raccourci clavier Ctrl + Alt + O. Le concepteur Visual Studio a généré le code pour lier le gestionnaire d’événements au formulaire si:
private void InitializeComponent() { // ... this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown); // ... }
J’ai donc essayé d’append un appel à Console.WriteLine()
au gestionnaire pour vérifier qu’il était appelé, mais pas de chance non plus.
En outre, j’ai essayé de définir un point d’arrêt sur l’appel de liaison d’événement (montré ci-dessus) et j’ai constaté que le programme atteignait ce point d’arrêt très bien. Mais tous les points d’arrêt que j’ai définis dans la définition même de la méthode ne sont jamais atteints.
Pour m’assurer que je faisais correctement les premières étapes, j’ai essayé de les répéter avec:
Une nouvelle forme dans la même solution. Même problème: le formulaire ne répond pas lorsque j’appuie sur le raccourci clavier Ctrl + Alt + O et que le débogueur n’entre pas dans le gestionnaire d’événements. J’ai essayé à nouveau et ça marche.
Une nouvelle solution WinForms.
Cela fonctionne parfaitement: la boîte de dialog de message apparaît (l’appel de Console.WriteLine()
fonctionne également).
Donc je suis assez perdu ici. Qu’est-ce qui empêche tous les formulaires de ce projet de recevoir des événements KeyDown?
Votre formulaire possède-t-il la propriété KeyPreview définie sur true?
Propriété Form.KeyPreview
Obtient ou définit une valeur indiquant si le formulaire recevra des événements clés avant que l’événement ne soit transmis au contrôle qui a le focus.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
Le conseil le plus courant pour ce problème sur StackOverflow et MSDN 1 , 2 (y compris la réponse acceptée ici) est simple et rapide:
KeyDown
événementsKeyDown
sont déclenchés sur unForm
tant que sa propriétéKeyPreview
est définie surtrue
C’est suffisant pour la plupart des objectives, mais c’est risqué pour deux raisons:
KeyDown
gestionnaires KeyDown
ne voient pas toutes les clés . Plus précisément, “vous ne pouvez pas voir le type de frappe utilisé pour la navigation. Comme les touches de curseur et Tab, Echap et Entrée pour une boîte de dialog.”
Il existe différentes manières d’intercepter les événements clés, et ils se produisent tous en séquence. KeyDown
est traité en dernier . Par conséquent, KeyPreview
n’est pas vraiment un aperçu, et l’événement pourrait être réduit au silence à quelques arrêts.
(Crédit à @HansPassant pour ces points.)
Au lieu de cela, remplacez ProcessCmdKey
dans votre Form
:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.Up) { // Handle key at form level. // Do not send event to focused control by returning true. return true; } return base.ProcessCmdKey(ref msg, keyData); }
De cette façon, toutes les clés sont visibles pour la méthode et la méthode est la première en ligne pour voir l’événement.
Notez que vous avez toujours le contrôle sur le fait que les contrôles focalisés voient ou non l’événement KeyDown
. Il suffit de retourner true
pour bloquer l’événement KeyDown
, plutôt que de définir KeyPressEventArgs.Handled
sur true
comme vous le feriez dans un gestionnaire d’événements KeyDown
. Voici un article avec plus de détails.
Essayez de définir la propriété KeyPreview
sur votre formulaire sur true. Cela a fonctionné pour moi pour enregistrer des presses à clé.