2010-01-25 7 views
11

Nella mia applicazione, voglio consentire agli utenti di personalizzare le scorciatoie da tastiera, proprio come è fatto nelle opzioni della tastiera di Visual Studio. L'utente può mettere a fuoco una casella di testo vuota e quindi digitare qualsiasi collegamento che desidera assegnare a un comando.Come si legge la scorciatoia da tastiera personalizzata dall'utente in WPF?

Il più vicino Sono venuto per farlo funzionare è mediante la sottoscrizione per l'evento TextBox.PreviewKeyDown, impostandola come gestito per impedire l'immissione di testo attuale nella casella di testo. Quindi ignoro gli eventi KeyDown associati ai tasti modificatori (esiste un modo più semplice per determinare se una chiave è un tasto modificatore?).

// 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(); 

} 

I lavori di cui sopra per qualsiasi collegamento a partire da Ctrl e Ctrl + Maiusc, ma non riesce per qualsiasi scorciatoie Alt. L'e.Key è sempre impostato su Key.System quando premo un collegamento contenente Alt.

Come posso registrare i tasti di scelta rapida Alt dall'utente? Esiste un modo migliore e più robusto per registrare le scorciatoie da parte dell'utente?

+0

Ho la sensazione che il tasto Alt sia utilizzato da WPF per tentare di catturare una combinazione di tasti Alt per mettere a fuoco un controllo che è legato a un'etichetta con una scorciatoia mnemonica (come Alt + F per il menu _File o Alt + O per un pulsante _OK). Forse c'è un modo per prevenirlo o annullarlo? –

risposta

23

Il trucco è quello di utilizzare la proprietà SystemKey se la proprietà Key è impostato su 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(); 
} 

ho aggiunto le chiavi sinistra e destra Windows all'elenco di modifica, perché a volte apparivano nel nome della chiave di scelta rapida quando un complesso (Ctrl+Shift+Alt) combinazione di tasti digitata da una sessione di Terminal Server. Non sono mai presenti in Keyboard.Modifiers, tuttavia, dal momento che sono riservati alle scorciatoie globali, quindi non li gestisco lì.

Ho anche utilizzato un StringBuilder per evitare di creare troppe istanze string.

Questa soluzione funziona con qualsiasi combinazione di tasti, ad eccezione di Shift+Alt (il modificatore Alt non è visto in questo caso). Questo potrebbe essere un artefatto del mio ambiente di Terminal Server, quindi, quindi il tuo chilometraggio potrebbe variare.

Infine, ho aggiunto un menu _File alla finestra per vedere cosa sarebbe successo e il tasto di scelta rapida Alt+F è effettivamente intrappolato dalla casella di testo prima che raggiunga il menu, che sembra essere quello che vuoi.

+0

+1, soluzione migliore della mia. Non conoscevo la chiave Key = (e.Key == Key.System? E.SystemKey: e.Key); trucco :) –

+0

Funziona! Grazie mille! –

+0

bene, grazie per aver condiviso! – Califf

-1

Hi
se You used WPF-Command nell'applicazione è possibile utilizzare questo:

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

Questo non risponde alla domanda. La domanda è come leggere una combinazione di chiavi in ​​una casella di testo, non come definire i tasti di scelta rapida in XAML. – alexandrudicu

+1

Mentre questo non risponde alla domanda del poster originale, questa è in effetti la risposta che stavo cercando quando sono incappato in questo thread attraverso Google. Quindi, voglio solo far sapere agli altri, nel 2016, questa è un'ottima soluzione per il keybinding dell'intera finestra. – Kikootwo

Problemi correlati