2010-01-25 16 views
11

W mojej aplikacji chcę umożliwić użytkownikom dostosowywanie skrótów klawiaturowych, tak jak w opcjach klawiatury Visual Studio. Użytkownik może ustawić ostrość w pustym polu tekstowym, a następnie wpisać dowolny skrót, który chce przypisać do polecenia.Jak mogę odczytać niestandardowy skrót klawiaturowy od użytkownika w WPF?

Najbliżej, doszedłem do jego działania, subskrybując zdarzenie TextBox.PreviewKeyDown, ustawiając je jako obsługiwane, aby zapobiec wprowadzaniu tekstu w polu tekstowym. Zignorowałem następnie zdarzenia KeyDown powiązane z kluczami modyfikującymi (czy istnieje bardziej przejrzysty sposób określenia, czy klucz jest kluczem modyfikującym?).

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

} 

Powyższe prace dla dowolnego skrótu począwszy Ctrl + Shift i Ctrl, ale nie dla wszystkich skrótów Alt. E.Key jest zawsze ustawiony na Key.System po naciśnięciu skrótu zawierającego Alt.

Jak mogę nagrywać skróty Alt u użytkownika? Czy istnieje lepszy, bardziej niezawodny sposób zapisywania skrótów od użytkownika?

+0

Mam wrażenie, że klawisz WP jest używany przez WPF do próby przechwycenia kombinacji klawisza Alt w celu skupienia się na formantu, który jest powiązany z etykietą za pomocą skrótu mnemonicznego (np. Alt + F dla menu _File lub Alt + O dla przycisku _OK). Może istnieje sposób, aby temu zapobiec? –

Odpowiedz

23

Sztuką jest wykorzystanie właściwości SystemKey jeżeli nieruchomość Key jest ustawiony na 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(); 
} 

Dodałem lewe i prawe klucze Windows do listy modyfikatorów, ponieważ czasami pojawiały się w nazwie klawisza skrótu, gdy obiekt jest złożony (Ctrl+Shift+Alt) kombinacja klawiszy została wpisana z sesji serwera terminali. Nigdy nie są obecne w Keyboard.Modifiers, ponieważ są zarezerwowane dla skrótów globalnych, więc nie obsługuję ich w tym miejscu.

Użyłem również StringBuilder, aby uniknąć tworzenia zbyt wielu instancji string.

To rozwiązanie działa z każdą kombinacją klawiszy, z wyjątkiem Shift+Alt (modyfikator Alt nie występuje w takim przypadku). To może być artefakt mojego środowiska Terminal Server, więc twój przebieg może się różnić.

Na koniec dodałem menu _File do okna, żeby zobaczyć, co by się stało, a kluczem Alt+F skrót skutecznie uwięziony przez pole tekstowe zanim dotrze do menu, które wydaje się być to, co chcesz.

+0

+1, lepsze rozwiązanie niż moje. Nie wiedziałeś o kluczu kluczowym = (e.Key == Key.System? E.SystemKey: e.Key); trick :) –

+0

Działa! Dziękuję bardzo! –

+0

dobry, dzięki za udostępnienie! – Califf

-1

Hi
jeśli You used WPF-Command w aplikacji można użyć to:

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

To nie odpowiada na pytanie. Pytanie brzmi, jak odczytywać kombinację klawiszy w polu tekstowym, a nie jak definiować skróty klawiszowe w XAML. – alexandrudicu

+1

Chociaż nie jest to odpowiedź na oryginalny plakat, jest to w rzeczywistości odpowiedź, której szukałem, gdy natknąłem się na ten wątek poprzez szukanie w Google. Po prostu daj znać innym ludziom, w 2016 r. Jest to świetne rozwiązanie, dzięki któremu możesz skupić się na całym oknie. – Kikootwo

Powiązane problemy