2010-01-25 16 views
11

En mi aplicación, quiero permitir a los usuarios personalizar los atajos de teclado, al igual que en las opciones de teclado de Visual Studio. El usuario puede enfocar un cuadro de texto en blanco y luego escribir cualquier acceso directo que quiera asignar a un comando.¿Cómo leo el atajo de teclado personalizado del usuario en WPF?

Lo más cerca que he llegado a hacerlo funcionar es suscribiéndome al evento TextBox.PreviewKeyDown, configurándolo como manejado para evitar el ingreso de texto real en el cuadro de texto. Luego ignoro los eventos KeyDown asociados con las teclas modificadoras (¿hay alguna manera más clara de determinar si una clave es una tecla modificadora?).

// Code-behind 
private void ShortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    // The text box grabs all input 
    e.Handled = true; 

    if (e.Key == Key.LeftCtrl || 
     e.Key == Key.RightCtrl || 
     e.Key == Key.LeftAlt || 
     e.Key == Key.RightAlt || 
     e.Key == Key.LeftShift || 
     e.Key == Key.RightShift) 
     return; 

    string shortcutText = ""; 
    if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control) 
     shortcutText += "Ctrl+"; 
    if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift) 
     shortcutText += "Shift+"; 
    if ((Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt) 
     shortcutText += "Alt+"; 
    _ShortcutTextBox.Text = shortcutText + e.Key.ToString(); 

} 

Los trabajos anteriores para cualquier acceso directo a partir de Ctrl + Shift y Ctrl, pero falla por cualquier atajo Alt. La tecla e. Siempre se establece en Key.System cuando presiono un atajo que contiene Alt.

¿Cómo puedo grabar accesos directos alternativos del usuario? ¿Hay alguna manera mejor y más sólida de grabar accesos directos desde el usuario?

+0

Tengo la sensación de que la tecla Alt es utilizada por WPF para intentar capturar un combo de tecla Alt para enfocar un control que está vinculado a una etiqueta con un atajo mnemónico (como Alt + F para el menú _File, o Alt + O para un botón _OK). Tal vez hay una manera de prevenir o anular eso? –

Respuesta

23

El truco es usar la propiedad SystemKey si la propiedad Key se establece en Key.System:

private void ShortcutTextBox_PreviewKeyDown(object sender, KeyEventArgs e) 
{ 
    // The text box grabs all input. 
    e.Handled = true; 

    // Fetch the actual shortcut key. 
    Key key = (e.Key == Key.System ? e.SystemKey : e.Key); 

    // Ignore modifier keys. 
    if (key == Key.LeftShift || key == Key.RightShift 
     || key == Key.LeftCtrl || key == Key.RightCtrl 
     || key == Key.LeftAlt || key == Key.RightAlt 
     || key == Key.LWin || key == Key.RWin) { 
     return; 
    } 

    // Build the shortcut key name. 
    StringBuilder shortcutText = new StringBuilder(); 
    if ((Keyboard.Modifiers & ModifierKeys.Control) != 0) { 
     shortcutText.Append("Ctrl+"); 
    } 
    if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0) { 
     shortcutText.Append("Shift+"); 
    } 
    if ((Keyboard.Modifiers & ModifierKeys.Alt) != 0) { 
     shortcutText.Append("Alt+"); 
    } 
    shortcutText.Append(key.ToString()); 

    // Update the text box. 
    _ShortcutTextBox.Text = shortcutText.ToString(); 
} 

añadí las teclas Windows izquierda y derecha de la lista de modificadores, porque a veces aparecían en el nombre de la tecla de método abreviado cuando un complejo () 0) la combinación de teclas se tipeó desde una sesión de Terminal Server. Sin embargo, nunca están presentes en Keyboard.Modifiers, ya que están reservados para accesos directos globales, por lo que no los manejo allí.

También usé StringBuilder para evitar crear demasiadas instancias de string.

Esta solución funciona con cualquier combinación de teclas, excepto Shift+Alt (el modificador Alt no se ve en ese caso). Sin embargo, eso podría ser un artefacto de mi entorno de Terminal Server, por lo que su kilometraje puede variar.

Por último, he añadido un menú _File a la ventana para ver qué pasaba, y la tecla de acceso directo Alt+F es atrapado de manera efectiva por el cuadro de texto antes de que llegue el menú, que parece ser lo que quieres.

+0

+1, mejor solución que la mía. No sabía acerca de la clave clave = (e.Key == Key.System? E.SystemKey: e.Key); truco :) –

+0

¡Trabajos! Muchas gracias! –

+0

bueno, ¡gracias por compartir! – Califf

-1

Hola
si You used WPF-Command en su aplicación puede utilizar este:

<Window.InputBindings> 
    <KeyBinding Command="YourCommnad" 
       Gesture="CTRL+C" /> 
</Window.InputBindings> 
+1

Esto no responde la pregunta. La pregunta es cómo leer una combinación de teclas en un cuadro de texto, no cómo definir teclas rápidas en XAML. – alexandrudicu

+1

Si bien esto no responde a la pregunta del cartel original, esta es de hecho la respuesta que estaba buscando cuando tropecé con este hilo a través de Google. Así que solo quiero que otras personas sepan, en 2016, esta es una gran solución para enlazar toda la ventana. – Kikootwo

Cuestiones relacionadas