Comment détecter les états des touches de modification dans WPF?

151

Existe-t-il des constructions globales que je peux utiliser chaque fois que j'ai besoin d'accéder si les boutons Control, Shift, Alt sont enfoncés? Par exemple à l'intérieurMouseDown événement d'un TreeView.

Si c'est le cas, comment?

Joan Venge
la source

Réponses:

257

Utilisez la classe Keyboard. En utilisant, Keyboard.IsKeyDownvous pouvez vérifier si Control, Shift, Alt est maintenant enfoncé.

Pour Shift:

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

Pour le contrôle:

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

Pour Alt:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Your code */ }
Kyrylo M
la source
125

Il y a aussi:

// 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
la source
13
Une bien meilleure solution. Il vous permet également de vérifier tous les modificateurs à la fois. Si vous voulez gérer Ctrl + F, vous ne voudrez pas gérer Ctrl + Maj + F, vous pouvez donc simplement vérifier au (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)lieu de tous les autres trucs ...
ygoe
35
Notez que les comparaisons dans les exemples ci-dessus produisent des résultats différents! Comme l'énumération ModifierKeys a l'attribut Flags, vous pouvez avoir n'importe quelle combinaison de valeurs dans l'énumération. Si vous voulez attraper UNIQUEMENT la touche Maj enfoncée, utilisez l' Keyboard.Modifiers == ModifierKeys.Shiftinstruction. Si vous voulez attraper la touche Maj mais que vous ne vous souciez pas si d'autres modificateurs sont pressés en même temps, utilisez la (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftsyntaxe HasFlag ou bien meilleureKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B
4
Je n'ai pas pu attraper le modificateur de touche Windows en utilisant cette méthode. (CTRL fonctionnait bien.) J'essayais d'attraperWIN+RightArrow .
ANeves
1
@ANeves Intéressant, Keyboard.Modifiersmontre commeNone
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
la source
2
Les réponses sont meilleures avec des commentaires et du code. Veuillez fournir un peu de contexte.
Chris
1
bonne idée de l'ajouter comme propriété
RollRoll
1
Lorsque j'ai utilisé PreviewKeyDown à la recherche de Alt + une autre clé, j'ai dû utiliser e.SystemKey au lieu de e.Key (la valeur de e.Key était "System" dans le cas de l'utilisation de alt + un autre caractère, dans mon cas)
Josh
3

C'est ainsi que je le gère (en utilisant PreviewKeyDown), disons que nous recherchons Alt + R ...

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

Peut-être que quelqu'un peut expliquer pourquoi j'ai dû utiliser e.SystemKey et pas seulement e.Key, peut-être à cause du modificateur? mais cela a fonctionné parfaitement pour moi lors de la recherche de modificateur + touche.

Josh
la source
0

et aussi:

si My.Computer.Keyboard.ShiftKeyDown alors ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown

Rob
la source
0

Emprunt en partie à @Josh, et quelque peu similaire à @Krushik, et faisant également référence à une question sur la différence entre KeyEventArgs.systemKey et KeyEventArgs.Key (répondant aux raisons pour lesquelles Josh doit utiliser SystemKey); dans lequel, avec des touches de modification (telles que Alt), e.Key renvoie Key.System, et donc la clé «réelle» est dans e.SystemKey.

Un moyen de contourner ce problème consiste à récupérer d'abord la clé `` réelle '', puis à faire votre conditionnel:

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
la source