Jak wykryć stany klucza modyfikatora w WPF?

151

Czy istnieją jakieś globalne konstrukcje, których mogę użyć, gdy potrzebuję dostępu do przycisków Control, Shift, Alt? Na przykład wewnątrz MouseDownzdarzenia TreeView.

Jeśli tak to jak?

Joan Venge
źródło

Odpowiedzi:

257

Użyj klasy Keyboard. Używając Keyboard.IsKeyDownmożesz sprawdzić, czy Control, Shift, Alt są teraz wyłączone.

Na zmianę:

if (Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift))
{ /* Your code */ }

Do kontroli:

if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{ /* Your code */ }

Dla Alt:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }
Kyrylo M
źródło
125

Jest także:

// Have to get this value before opening a dialog, or user will have released the control key
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{

}
Chuck Savage
źródło
13
Dużo lepsze rozwiązanie. Pozwala także na jednoczesne sprawdzenie wszystkich modyfikatorów. Jeśli chcesz obsłużyć Ctrl + F, nie będziesz chciał obsługiwać Ctrl + Shift + F, więc możesz po prostu sprawdzić (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)zamiast wszystkich innych rzeczy ...
ygoe
35
Zwróć uwagę, że porównania w powyższych przykładach dają różne wyniki! Ponieważ wyliczenie ModifierKeys ma atrybut Flags, możesz mieć dowolne kombinacje wartości w wyliczeniu. Jeśli chcesz złapać TYLKO naciśnięty klawisz Shift, użyj Keyboard.Modifiers == ModifierKeys.Shiftinstrukcji. Jeśli chcesz złapać klawisz Shift, ale nie obchodzi cię, czy inne modyfikatory są naciskane w tym samym czasie, użyj (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftlub znacznie lepszej składni HasFlagKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B
4
Nie udało mi się złapać modyfikatora klawisza Windows przy użyciu tej metody. (CTRL działało dobrze.) Próbowałem złapać WIN+RightArrow.
ANeves
1
@ANeves Ciekawe, Keyboard.Modifierspokazuje jakoNone
Chuck Savage
8
    private bool IsShiftKey { get; set; }

    private void OnPreviewKeyDown(object sender, KeyEventArgs e)
    {
        IsShiftKey = Keyboard.Modifiers == ModifierKeys.Shift ? true : false;

        if ((Key.Oem3 == e.Key || ((IsShiftKey && Key.Oem4 == e.Key) || (IsShiftKey && Key.Oem6 == e.Key) || (IsShiftKey && Key.Oem5 == e.Key)) && (validatorDefn as FormatValidatorDefinition).format == "packedascii"))
        {
           e.Handled = true;
        }
    }
Krushik
źródło
2
Odpowiedzi są lepsze z komentarzem i kodem. Proszę podać kontekst.
Chris,
1
świetny pomysł na dodanie go jako
właściwego
1
Kiedy użyłem PreviewKeyDown szukając Alt + inny klawisz, musiałem użyć e.SystemKey zamiast e.Key (wartość e.Key to "System" w przypadku użycia alt + inny znak, w moim przypadku)
Josh
3

Tak sobie z tym radzę (za pomocą PreviewKeyDown), powiedzmy, że szukamy Alt + R ...

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt)
       && e.SystemKey == Key.R)
    {
       //do whatever
    }
}

Może ktoś wyjaśni, dlaczego musiałem użyć e.SystemKey a nie tylko e.Key, może ze względu na modyfikator? ale to zadziałało bezbłędnie dla mnie podczas wyszukiwania modyfikatora + klawisz.

Josh
źródło
0

a także:

if My.Computer.Keyboard.ShiftKeyDown to ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown

Obrabować
źródło
0

Częściowo pożyczam od @Josh i trochę podobny do @Krushik, a także odnosząc się do pytania o różnicę między KeyEventArgs.systemKey i KeyEventArgs.Key (odpowiedź, dlaczego Josh musi używać SystemKey); gdzie, z klawiszami modyfikującymi (takimi jak Alt), e.Key zwraca Key.System, a zatem 'prawdziwy' klucz znajduje się w e.SystemKey.

Aby obejść ten problem, najpierw pobierz „prawdziwy” klucz, a następnie wykonaj warunek:

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    // Fetch the real key.
    var key = e.Key == Key.System ? e.SystemKey : e.Key;

    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
        && key == Key.Return)
    {
        // Execute your code.
    }
}
Elliot
źródło