Przez jakiś czas pracowałem nad projektem Windows Forms i zdecydowałem się poeksperymentować ze skrótami klawiaturowymi. Po lekturze doszedłem do wniosku, że muszę po prostu napisać procedurę obsługi zdarzeń i powiązać ją ze zdarzeniem KeyDown formularza:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.O)
{
MessageBox.Show("Ctrl+Alt+O: magic!");
}
}
Zrobiłem to starym dobrym sposobem na otwarcie panelu Właściwości projektanta programu Visual Studio, a następnie dwukrotne kliknięcie zdarzenia KeyDown w moim formularzu, aby wygenerować Form1_KeyDown
procedurę obsługi zdarzeń. Ale podczas testowania mojej aplikacji formularz w ogóle nie reaguje na skrót klawiaturowy Ctrl+ Alt+ O. Projektant programu Visual Studio wygenerował jednak kod, aby powiązać procedurę obsługi zdarzeń z formularzem:
private void InitializeComponent()
{
// ...
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
// ...
}
Więc spróbowałem dodać Console.WriteLine()
wywołanie do programu obsługi, aby sprawdzić, czy w ogóle jest wywoływany, ale też bez powodzenia.
Próbowałem również ustawić punkt przerwania w wywołaniu powiązania zdarzenia (pokazanym powyżej) i stwierdziłem, że program osiąga ten punkt przerwania w porządku. Ale żadne punkty przerwania, które ustawiłem w samej definicji metody, nigdy nie są osiągane.
Aby upewnić się, że kilka pierwszych kroków wykonałem poprawnie, spróbowałem je powtórzyć z:
Nowa forma w tym samym rozwiązaniu.
Ten sam problem: formularz nie odpowiada, gdy naciskam skrót klawiaturowy Ctrl+ Alt+, Oa debugger nie wchodzi nawet do modułu obsługi zdarzeń.Próbowałem tego ponownie i działa.Zupełnie nowe rozwiązanie WinForms.
Działa idealnie: pojawia się okno dialogowe wiadomości (Console.WriteLine()
połączenie również działa).
Więc jestem tu zagubiony. Co uniemożliwia wszystkim formularzom w tym jednym projekcie otrzymywanie zdarzeń KeyDown?
Najczęstsza rada dotycząca tego problemu w StackOverflow i MSDN 1 , 2 (w tym zaakceptowana odpowiedź tutaj) jest szybka i łatwa:
Jest to wystarczające do większości celów, ale jest ryzykowne z dwóch powodów:
KeyDown
programy obsługi nie widzą wszystkich kluczy . W szczególności „nie widać naciśnięć klawiszy, które są używane do nawigacji. Podobnie jak klawisze kursora i Tab, Escape i Enter w oknie dialogowym”.Istnieje kilka różnych sposobów przechwytywania kluczowych wydarzeń i wszystkie one następują po kolei.
KeyDown
jest obsługiwany jako ostatni . W związku z tymKeyPreview
nie jest to zbyt duży podgląd, a wydarzenie można by wyciszyć na kilku przystankach po drodze.(Podziękowania dla @HansPassant za te punkty).
Zamiast tego zastąp
ProcessCmdKey
wForm
: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); }
W ten sposób wszystkie klucze są widoczne dla metody, a metoda jest pierwsza w kolejce, aby zobaczyć zdarzenie.
Zwróć uwagę, że nadal masz kontrolę nad tym, czy aktywne kontrolki widzą
KeyDown
zdarzenie. Po prostu wróć,true
aby zablokować kolejneKeyDown
zdarzenie, zamiast ustawiaćKeyPressEventArgs.Handled
jetrue
tak, jak wKeyDown
przypadku obsługi zdarzeń. Oto artykuł ze szczegółami.źródło
Spróbuj ustawić
KeyPreview
właściwość w formularzu na true. Pomogło mi to w rejestrowaniu naciśnięć klawiszy.źródło