2010-06-23 15 views
25

Tengo un código que (se supone que debe) capturar pulsaciones de teclas. La ventana de nivel superior tiene una cláusulaPreviewKeyDown no está viendo modificadores de Alt

Keyboard.PreviewKeyDown="Window_PreviewKeyDown" 

y el archivo CS soporte 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; 
     } 
    } 
} 

Ahora que funciona bien, tanto CTRLL y CTRLR llamada de la correspondiente funciones.

Tan pronto como cambie la comprobación del modificador para usar ModifierKeys.Alt, deja de funcionar. En otras palabras, ni ALTL y ALTR llamar a las funciones.

¿Qué me falta aquí?

Respuesta

40

En caso de un modificador Alt, e.Key devuelve Key.System y la clave real está en e.SystemKey. Se puede utilizar el siguiente fragmento de código para obtener siempre la tecla pulsada correcta:

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

impresionante. Muchas gracias. – mbaytas

47

El problema es que cuando Alt se mantiene presionado sus KeyEventArgs tiene:

Key = Key.System 
SystemKey = the real key 

por lo que cuando la comprobación de Alt necesita e.SystemKey utilizar en lugar de e.Key, así:

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

Explicación

En Windows, la tecla "Alt" se maneja especialmente. Cuando se presiona la tecla Alt o se presiona otra tecla mientras se mantiene presionada la tecla Alt, se considera una pulsación de tecla del "Sistema". Las pulsaciones de tecla del "Sistema" se manejan de forma diferente a las pulsaciones de teclas regulares de muchas maneras.

Todo comienza cuando Windows pasa la pulsación de tecla a su aplicación. Los eventos normales de tecla descendente generan un WM_KEYDOWN, pero si se presiona la tecla Alt, genera un WM_SYSKEYDOWN. Por la misma razón, WM_KEYUP se traduce a WM_SYSKEYUP.

En Windows, incluido en WPF, el manejo especial de la tecla Alt se utiliza con elementos de menú, botones y etiquetas que incluyen "texto de acceso". Por ejemplo, si un botón tiene contenido de "Decir _Hi", presionar Alt-H se tratará como un clic de botón.

Cuando la tecla Alt está presionada, las letras aparecen como tres pares de eventos: KeyDown, KeyUp y TextInput, cada uno con sus versiones de vista previa asociadas. Las principales diferencias aquí son:

  • los eventos KeyDown y KeyUp tener su propiedad Key establece en "Key.System" en lugar de la llave que se ha pulsado, y la SystemKey ajustado a la tecla pulsada real.
  • evento El TextInput se pasa normalmente pero luego manejado como un AccessKey si no se consume
+0

¿Ese segundo bloque de código debe ser 'ModifierKeys.Alt'? – paxdiablo

+1

Gracias, Ray, la explicación fue una ventaja añadida así que +1 por eso. – paxdiablo

+1

Excelente explicación! +1 para usted Señor – Arcturus

Cuestiones relacionadas