Ich habe eine Weile an meinem Windows Forms-Projekt gearbeitet und mich entschlossen, mit Tastaturkürzeln zu experimentieren. Nach einigem Lesen dachte ich, ich müsste nur einen Ereignishandler schreiben und ihn an das KeyDown-Ereignis des Formulars binden:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.O)
{
MessageBox.Show("Ctrl+Alt+O: magic!");
}
}
Ich habe dies auf die gute alte Weise getan, um das Eigenschaftenfenster des Visual Studio-Designers zu öffnen und dann auf das KeyDown-Ereignis meines Formulars zu doppelklicken, um den Form1_KeyDown
Ereignishandler zu generieren . Beim Testen meiner Anwendung reagiert das Formular jedoch überhaupt nicht auf die Tastenkombination Ctrl+ Alt+ O. Der Visual Studio-Designer hat den Code generiert, um den Ereignishandler an das Formular zu binden:
private void InitializeComponent()
{
// ...
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
// ...
}
Also habe ich versucht Console.WriteLine()
, dem Handler einen Anruf hinzuzufügen , um zu überprüfen, ob er überhaupt aufgerufen wurde, aber auch kein Glück.
Außerdem habe ich versucht, einen Haltepunkt für den Ereignisbindungsaufruf (siehe oben) festzulegen, und festgestellt, dass das Programm diesen Haltepunkt einwandfrei erreicht. Haltepunkte, die ich in der Methodendefinition selbst festgelegt habe, werden jedoch nie erreicht.
Um sicherzustellen, dass ich die ersten Schritte korrekt ausgeführt habe, habe ich versucht, sie zu wiederholen mit:
Eine neue Form in der gleichen Lösung.
Gleiches Problem: Das Formular reagiert nicht, wenn ich die Tastenkombination Ctrl+ Alt+ drücke Ound der Debugger nicht einmal in den Ereignishandler tritt.Versuchte dies erneut und es funktioniert.Eine brandneue WinForms-Lösung.
Es funktioniert perfekt: Der Nachrichtendialog wird angezeigt (derConsole.WriteLine()
Anruf funktioniert auch).
Also bin ich hier ziemlich verloren. Was hindert alle Formulare in diesem einen Projekt daran, KeyDown-Ereignisse zu empfangen?
Der häufigste Ratschlag für dieses Problem bei StackOverflow und MSDN 1 , 2 (einschließlich der hier akzeptierten Antwort) ist schnell und einfach:
Das ist für die meisten Zwecke ausreichend, aber aus zwei Gründen riskant:
KeyDown
Handler sehen nicht alle Schlüssel . Insbesondere "Sie können die Art der Tastenanschläge, die für die Navigation verwendet werden, nicht sehen. Wie die Cursortasten und die Tabulatortaste, Escape und Enter für einen Dialog."Es gibt verschiedene Möglichkeiten, Schlüsselereignisse abzufangen, und alle treten nacheinander auf.
KeyDown
wird zuletzt behandelt . DaherKeyPreview
ist es keine große Vorschau, und das Ereignis könnte an einigen Haltestellen auf dem Weg zum Schweigen gebracht werden.(Gutschrift an @HansPassant für diese Punkte.)
Überschreiben
ProcessCmdKey
Sie stattdessen FolgendesForm
: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); }
Auf diese Weise sind alle Schlüssel für die Methode sichtbar, und die Methode steht an erster Stelle, um das Ereignis anzuzeigen.
Beachten Sie, dass Sie weiterhin die Kontrolle darüber haben, ob fokussierte Steuerelemente das
KeyDown
Ereignis sehen oder nicht . Kehren Sie einfach zurücktrue
, um das nachfolgendeKeyDown
Ereignis zu blockieren , anstattKeyPressEventArgs.Handled
estrue
wie in einemKeyDown
Ereignishandler festzulegen. Hier ist ein Artikel mit mehr Details.quelle
Versuchen Sie, die
KeyPreview
Eigenschaft in Ihrem Formular auf true zu setzen. Dies funktionierte bei mir für die Registrierung von Tastendrücken.quelle