2010-07-21 9 views
6

Grundsätzlich habe ich ein Formular mit einem benutzerdefinierten Steuerelement (und nichts anderes). Das benutzerdefinierte Steuerelement ist vollständig leer und das Formular hat KeyPreview auf True festgelegt.Pfeil Schlüsselereignisse nicht ankommen

Mit diesem Setup erhalte ich keine KeyDown-Ereignisse für irgendwelche Pfeiltasten oder Tab. Jede andere Taste, die ich auf meiner Tastatur habe, funktioniert. Ich habe KeyDown Event Handler an alles angeschlossen, was solche Ereignisse hat, also bin ich sicher, dass ich nichts vermisse.

Auch ist von Bedeutung, wenn ich das (völlig leere) benutzerdefinierte Steuerelement entfernen, bekomme ich die Pfeiltaste Ereignisse.

Was um alles in der Welt geht hier vor?

EDIT:

Ich habe diese sowohl für die Form und die Kontrolle, aber ich bin noch nicht Pfeiltasten bekommen:

protected override void WndProc(ref Message m) { 
    switch (m.Msg) { 
     case 0x100: //WM_KEYDOWN 
      //this is the control's version. In the form, it's this.Text 
      ParentForm.Text = ((Keys)m.WParam).ToString(); 
      break; 
    } 
    base.WndProc(ref m); 
} 

ich auch mit Spy ++ überprüft und festgestellt, dass die Form selbst Es werden keine WM_KEYDOWN-Nachrichten empfangen, sie gehen alle zum Steuerelement. Wie dem auch sei, das Steuerelement erhält die Pfeiltaste WM_KEYDOWN Nachrichten. Seufzer.

Edit 2: Ich habe auch die ZIP-Datei mit dieser Version aktualisiert. Bitte schauen Sie es, wenn Sie helfen möchten, ...

bearbeiten 3:

ich dies herausgefunden haben, irgendwie. Das Formular isst die Pfeiltasten, wahrscheinlich in einem Versuch, Fokus unter seinen Kindern zu behalten. Dies wird durch die Tatsache bewiesen, dass ich die Ereignisse bekomme, wenn das Formular leer ist.

Wie auch immer, wenn ich diesen Code zum Formular hinzufügen, fange ich wieder die Ereignisse bekommen:

public override bool PreProcessMessage(ref Message msg) { 
    switch (msg.Msg) { 
     case 0x100: //WM_KEYDOWN 
      return false; 
    } 
    return base.PreProcessMessage(ref msg); 
} 

Wenn ich dies außer Kraft setzen, wird das Formular nicht die Chance bekommen ihre schmutzige Arbeit zu tun, und so Ich bekomme meine KeyDown-Ereignisse wie erwartet. Ich nehme an, dass ein Nebeneffekt davon ist, dass ich nicht mehr meine Tastatur verwenden kann, um das Formular zu navigieren (keine große Sache in diesem Fall, da es ein Spiel ist, und der ganze Zweck dieser Übung ist, Tastaturnavigation zu implementieren!)

Die Frage bleibt immer noch darüber, wie diese „richtig“ zu deaktivieren, wenn es einen Weg gibt ...

+0

Es hört sich an, als ob das Formular, in dem sich Ihr Benutzersteuerelement befindet, das Ereignis erfasst und es so konfiguriert, dass es behandelt wird, bevor Ihr Benutzersteuerelement es empfängt. Stellen Sie sicher, dass Ihr Benutzersteuerelement beim Drücken der Taste den Fokus hat? –

Antwort

10

Ich habe einige umfangreiche Tests durchgeführt, und ich habe alles herausgefunden.I wrote a blog post detailing the solution.

Kurz gesagt, wollen Sie die ProcessDialogKey Methode in Form außer Kraft zu setzen:

protected override bool ProcessDialogKey(Keys keyData) { 
    return false; 
} 

Dies wird mit den Pfeiltasten (und Reiter) verursachen als normale KeyDown- Ereignisse geliefert werden. JEDOCH! Dies führt auch dazu, dass die normale Dialogtastenfunktionalität (Verwendung der Registerkarte zum Navigieren in Steuerelementen usw.) fehlschlägt. Wenn Sie das behalten wollen, aber immer noch das KeyDown-Ereignis zu erhalten, verwenden Sie stattdessen:

protected override bool ProcessDialogKey(Keys keyData) { 
    OnKeyDown(new KeyEventArgs(keyData)); 
    return base.ProcessDialogKey(keyData); 
} 

Dies wird eine KeyDown- Nachricht liefern, während immer noch normalen Dialog Navigation zu tun.

+0

Funktioniert wie ein Charme. – Carra

+0

Danke! Funktioniert perfekt! –

+0

Ihr Blog-Link ist tot?!? –

0

wenn Fokus Ihr Problem ist, und man kann es nicht die Kontrolle bekommen Anwender einen Fokus zu nehmen und halten Eine einfache Umgehungslösung wäre, das Ereignis für das Benutzer-Ereignis auf dem Schlüsselereignis zu wiederholen, um das Sie sich Sorgen machen. Abonnieren Sie Ihre Formular-Keydown- oder -Tastenereignisse, und lassen Sie dann dieses Ereignis ein Ereignis für Ihr Benutzersteuerelement auslösen.

Also, im Wesentlichen würde Form1_KeyPress UserControl1_KeyPress mit den Absender-und Ereignisargumente von Form1_KeyPress z.

protected void Form1_KeyPress(object sender, KeyEventArgs e) 
{ 
    UserControl1_KeyPress(sender, e); 
} 

Andernfalls können Sie den langen Weg zu nehmen und Ihre WndProc Ereignisse überschreiben, um die Funktionalität zu erhalten Sie wünschen.

+0

Das UserControl ist leer und kann keinen Fokus erhalten (AFAIK). Daher sollte das Formular selbst die KeyDown-Ereignisse empfangen. Es ist jedoch nicht. Wie ich in der Frage gesagt habe, habe ich Event-Handler an alles angeschlossen, was das Event hat, aber nichts bekommt das Event. Ich kann versuchen, WndProc zu überschreiben, aber ich sollte wirklich nicht müssen ... –

+0

Ich habe das OP mit den Ergebnissen meines übergeordneten WndProc aktualisiert –

Verwandte Themen