PreviewKeyDown non visualizza i modificatori Alt

Ho un codice che è (dovrebbe essere) che cattura i tasti. La finestra di livello superiore ha a

Keyboard.PreviewKeyDown="Window_PreviewKeyDown" 

la clausola e il file CS di supporto contiene:

 private void Window_PreviewKeyDown(object sender, KeyEventArgs e) { if (e.KeyboardDevice.Modifiers == ModifierKeys.Control) { switch (e.Key) { case Key.L: btnPrev_Click(sender, new RoutedEventArgs()); e.Handled = true; break; case Key.R: btnNext_Click(sender, new RoutedEventArgs()); e.Handled = true; break; } } } 

Ora che funziona bene, sia CTRL L che CTRL R chiamano le funzioni rilevanti.

Non appena cambio il controllo Modifer per usare ModifierKeys.Alt , smette di funzionare. In altre parole, né ALT LALT R chiamano le funzioni.

Cosa mi manca qui?

In caso di un modificatore Alt , e.Key restituisce Key.System e la chiave reale è in e.SystemKey . È ansible utilizzare la seguente parte di codice per ottenere sempre il tasto premuto corretto:

 Key key = (e.Key == Key.System ? e.SystemKey : e.Key); 

Il problema è che quando Alt viene tenuto premuto, KeyEventArgs ha:

 Key = Key.System SystemKey = the real key 

quindi quando controlli Alt ti serve usare e.SystemKey invece di e.Key, come questo:

 if (e.KeyboardDevice.Modifiers == ModifierKeys.Alt) { switch (e.SystemKey) { ... 

Spiegazione

Sotto Windows, il tasto “Alt” è gestito appositamente. Quando si preme il tasto Alt stesso o si preme un altro tasto mentre si tiene premuto il tasto Alt, viene considerata una pressione del tasto “Sistema”. I tasti “Sistema” vengono gestiti in modo diverso rispetto ai normali pressioni dei tasti in molti modi.

Tutto inizia quando Windows passa la pressione del tasto all’applicazione. I normali eventi down del tasto generano un WM_KEYDOWN, ma se viene premuto il tasto Alt genera un WM_SYSKEYDOWN. Allo stesso modo un WM_KEYUP è tradotto in un WM_SYSKEYUP.

In Windows, incluso in WPF, la gestione speciale del tasto Alt viene utilizzata con MenuItem, Pulsanti ed etichette che includono “testo di accesso”. Ad esempio, se un pulsante ha il contenuto di “Say _Hi”, quindi presing Alt-H verrà considerato come un clic del pulsante aa.

Quando il tasto Alt è distriggersto, le lettere si presentano come tre coppie di eventi: KeyDown, KeyUp e TextInput, ciascuna con le relative versioni di anteprima associate. Le principali differenze qui sono:

  • Gli eventi KeyDown e KeyUp hanno la proprietà Key impostata su “Key.System” anziché il tasto effettivo premuto e il SystemKey impostato sul tasto effettivo premuto.
  • L’evento TextInput viene passato normalmente ma poi gestito come AccessKey se non viene utilizzato