Como detectar estados de chave modificadora no WPF?

151

Há algumas construções globais que eu posso usar sempre que precisar acessar se os botões Control, Shift, Alt estão pressionados? Por exemplo, MouseDownevento interno de a TreeView.

Se sim, como?

Joan Venge
fonte

Respostas:

257

Use classe Keyboard. Usando Keyboard.IsKeyDownvocê pode verificar se Control, Shift, Alt está desativado agora.

Para Turno:

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

Para controle:

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

Para Alt:

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

Há também:

// 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
fonte
13
Solução muito melhor. Também permite que você verifique todos os modificadores de uma só vez. Se você deseja lidar com Ctrl + F, você não vai querer lidar com Ctrl + Shift + F, para que pudesse verificar (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)em vez de todas as outras coisas ...
ygoe
35
Observe que as comparações nos exemplos acima produzem resultados diferentes! Como a enumeração ModifierKeys possui o atributo Flags, você pode ter qualquer combinação de valores na enumeração. Se você deseja capturar SOMENTE a tecla Shift pressionada, use a Keyboard.Modifiers == ModifierKeys.Shiftinstrução Se você quiser pegar a tecla shift, mas cuidado Não se outros modificadores são pressionadas ao mesmo tempo, use o (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftou o muito melhor sintaxe HasFlagKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B
4
Não consegui pegar o modificador de chave do Windows usando esse método. (CTRL funcionou bem.) Eu estava tentando pegar WIN+RightArrow.
ANeves
1
@ANeves Interessante, Keyboard.Modifiersmostra comoNone
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
fonte
2
As respostas são melhores com comentários e código. Forneça algum contexto.
Chris
1
grande ideia de adicionar-lo como um proprerty
RollRoll
1
Quando usei o PreviewKeyDown procurando Alt + outra chave, tive que usar o e.SystemKey em vez do e.Key (o valor do e.Key era "System" no caso de usar alt + outro caractere, no meu caso)
Josh
3

É assim que eu manejo isso (usando o PreviewKeyDown), digamos que estamos procurando Alt + R ...

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

Talvez alguém possa esclarecer por que eu tive que usar o e.SystemKey e não apenas o e.Key, talvez devido ao modificador? mas isso funcionou perfeitamente para mim ao procurar pelo modificador + chave.

Josh
fonte
0

e também:

se My.Computer.Keyboard.ShiftKeyDown então ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown

Roubar
fonte
0

Parcialmente emprestado do @Josh e um pouco semelhante ao @Krushik, e também fazendo referência a uma pergunta sobre a diferença entre KeyEventArgs.systemKey e KeyEventArgs.Key (respondendo por que Josh precisa usar o SystemKey); em que, com as teclas modificadoras (como Alt), o e.Key retorna Key.System e, portanto, a chave 'real' está dentro do e.SystemKey.

Uma maneira de contornar isso é buscar primeiro a chave 'real' e, em seguida, fazer o seu condicional:

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
fonte