Wie erkenne ich Modifikatorschlüsselzustände in WPF?

150

Gibt es einige globale Konstrukte, die ich verwenden kann, wenn ich darauf zugreifen muss, ob die Schaltflächen Strg, Umschalt, Alt gedrückt sind? Zum Beispiel innerhalb eines MouseDownEreignisses von a TreeView.

Wenn das so ist, wie?

Joan Venge
quelle

Antworten:

257

Klasse verwenden Keyboard. Mit können Keyboard.IsKeyDownSie überprüfen, ob Strg, Umschalt, Alt jetzt deaktiviert ist.

Für die Schicht:

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

Zur Kontrolle:

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

Für Alt:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }
Kyrylo M.
quelle
124

Es gibt auch:

// 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
quelle
13
Viel bessere Lösung. Außerdem können Sie alle Modifikatoren gleichzeitig überprüfen. Wenn Sie mit Strg + F umgehen möchten, möchten Sie nicht mit Strg + Umschalt + F umgehen, sodass Sie (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)anstelle aller anderen
Dinge nachsehen können
35
Beachten Sie, dass die Vergleiche in den obigen Beispielen zu unterschiedlichen Ergebnissen führen! Da die ModifierKeys-Aufzählung das Flags-Attribut hat, können Sie beliebige Wertekombinationen in der Aufzählung haben. Wenn Sie NUR die gedrückte Umschalttaste abfangen möchten, verwenden Sie die Keyboard.Modifiers == ModifierKeys.ShiftAnweisung. Wenn Sie die Umschalttaste abfangen möchten, sich aber nicht darum kümmern, ob andere Modifikatoren gleichzeitig gedrückt werden, verwenden Sie die (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftoder die viel bessere HasFlag-SyntaxKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B
4
Ich konnte den Windows-Schlüsselmodifikator mit dieser Methode nicht abfangen. (STRG hat gut funktioniert.) Ich habe versucht zu fangen WIN+RightArrow.
Aneves
1
@ ANeves Interessant, Keyboard.Modifierszeigt alsNone
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
quelle
2
Antworten sind sowohl mit Kommentaren als auch mit Code besser. Bitte geben Sie einen Kontext an.
Chris
1
Tolle Idee, es als Eigentum hinzuzufügen
RollRoll
1
Als ich PreviewKeyDown verwendete, um nach Alt + einem anderen Schlüssel zu suchen, musste ich e.SystemKey anstelle von e.Key verwenden (der Wert von e.Key war "System", wenn ich alt + ein anderes Zeichen verwendete, in meinem Fall)
Josh
3

So gehe ich damit um (mit PreviewKeyDown), sagen wir, wir suchen nach Alt + R ...

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

Vielleicht kann jemand klären, warum ich e.SystemKey und nicht nur e.Key verwenden musste, vielleicht aufgrund des Modifikators? Aber das hat bei der Suche nach Modifikator + Schlüssel einwandfrei funktioniert.

Josh
quelle
0

und auch:

wenn My.Computer.Keyboard.ShiftKeyDown dann ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown

rauben
quelle
0

Teilweise von @Josh entlehnt und @Krushik etwas ähnlich, und auch auf eine Frage zum Unterschied zwischen KeyEventArgs.systemKey und KeyEventArgs.Key verweisen (Antwort darauf, warum Josh SystemKey verwenden muss); wobei mit Modifikatortasten (wie Alt) e.Key Key.System zurückgibt und sich somit der 'echte' Schlüssel innerhalb von e.SystemKey befindet.

Eine Möglichkeit, dies zu umgehen, besteht darin, zuerst den "echten" Schlüssel abzurufen und dann Ihre Bedingung zu erfüllen:

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
quelle