172 votes

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

Y a-t-il des constructions globales que je puisse utiliser chaque fois que j'ai besoin de vérifier si les boutons Control, Shift, Alt sont enfoncés? Par exemple à l'intérieur de l'événement MouseDown d'un TreeView.

Si oui, comment faire?

292voto

kirmir Points 3825

Utilisez la classe Keyboard. En utilisant Keyboard.IsKeyDown, vous pouvez vérifier si Control, Shift, Alt sont enfoncées actuellement.

Pour Shift:

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

Pour Control:

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

Pour Alt:

if (Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
{ /* Votre code */ }

134voto

Chuck Savage Points 6106

Il y a aussi :

// Doit obtenir cette valeur avant d'ouvrir une boîte de dialogue, sinon l'utilisateur aura relâché la touche de contrôle
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{

}

13 votes

Une bien meilleure solution. Cela vous permet également de vérifier tous les modificateurs en une seule fois. Si vous voulez gérer Ctrl+F, vous ne voudrez pas gérer Ctrl+Shift+F, vous pouvez donc simplement vérifier (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control) au lieu de tout le reste...

36 votes

Veuillez noter 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 toutes les combinaisons de valeurs dans l'énumération. Si vous voulez attraper SEULEMENT la touche Maj enfoncée, utilisez l'instruction Keyboard.Modifiers == ModifierKeys.Shift. Si vous voulez attraper la touche Maj mais ne vous souciez pas des autres modificateurs enfoncés en même temps, utilisez la syntaxe (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift ou la syntaxe de HasFlag beaucoup meilleure Keyboard.Modifiers.HasFlag(ModifierKeys.Shift)

4 votes

Je n'ai pas pu attraper le modificateur de touche Windows en utilisant cette méthode. (CTRL a bien fonctionné.) J'essayais d'attraper WIN+flèche droite.

9voto

Krushik Points 1
    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;
        }
    }

2 votes

Les réponses sont meilleures avec des commentaires ainsi que du code. Veuillez fournir un peu de contexte.

1 votes

Excellente idée d'ajouter cela comme une propriété

1 votes

Lorsque j'ai utilisé PreviewKeyDown à la recherche d'Alt + une autre touche, j'ai dû utiliser e.SystemKey au lieu de e.Key (la valeur de e.Key était "System" dans le cas où alt+un autre caractère était utilisé, dans mon cas)

6voto

Josh Points 601

Voici comment 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 m'expliquer pourquoi j'ai dû utiliser e.SystemKey et non simplement e.Key, peut-être en raison du modificateur? mais cela a fonctionné à merveille pour moi lorsque je cherchais un modificateur+clé.

5voto

Elliot Points 39

En partie inspiré par @Josh, et quelque peu similaire à @Krushik, faisant également référence à une question sur la Différence entre KeyEventArgs.systemKey et KeyEventArgs.Key (expliquant pourquoi Josh doit utiliser SystemKey) ; dans le cas des touches de modification (telles que Alt), e.Key renvoie Key.System, et donc la touche 'réelle' se trouve dans e.SystemKey.

Une solution à cela est de d'abord récupérer la touche 'réelle', puis de faire votre condition:

private void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
    // Récupérer la touche réelle.
    var key = e.Key == Key.System ? e.SystemKey : e.Key;

    if ((Keyboard.IsKeyDown(Key.LeftAlt) || Keyboard.IsKeyDown(Key.RightAlt))
        && key == Key.Return)
    {
        // Exécutez votre code.
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X