¿Cómo detectar estados clave modificadores en WPF?

151

¿Hay algunas construcciones globales que puedo usar cuando necesito acceder si los botones Control, Shift, Alt están presionados? Por ejemplo dentroMouseDown evento de a TreeView.

¿Si es así, cómo?

Joan Venge
fuente

Respuestas:

257

Usa la clase Keyboard. Utilizando Keyboard.IsKeyDownpuedes comprobar si Control, Shift, Alt está abajo ahora.

Por turno:

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

Para el control:

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
fuente
125

También hay:

// 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
fuente
13
Mucho mejor solución. También le permite verificar todos los modificadores a la vez. Si desea manejar Ctrl + F, no querrá manejar Ctrl + Shift + F, por lo que puede verificar en (e.Key == Key.F && e.KeyboardDevice.Modifiers == ModifierKeys.Control)lugar de todas las demás cosas ...
ygoe
35
¡Tenga en cuenta que las comparaciones en los ejemplos anteriores producen resultados diferentes! Como la enumeración ModifierKeys tiene el atributo Banderas, puede tener cualquier combinación de valores en la enumeración. Si desea atrapar SOLAMENTE la tecla shift presionada, use la Keyboard.Modifiers == ModifierKeys.Shiftinstrucción. Si desea captar la tecla Mayús pero no le importa si se presionan otros modificadores al mismo tiempo, use la (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shiftsintaxis HasFlag o la mejor sintaxisKeyboard.Modifiers.HasFlag(ModifierKeys.Shift)
Patrik B
44
No pude atrapar el modificador de clave de Windows usando este método. (CTRL funcionó bien.) Estaba tratando de atraparlo WIN+RightArrow.
ANeves
1
@ANeves Interesante, se Keyboard.Modifiersmuestra 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
fuente
2
Las respuestas son mejores tanto con comentarios como con código. Por favor proporcione un poco de contexto.
Chris
1
gran idea de agregarlo como propiedad
RollRoll
1
Cuando utilicé PreviewKeyDown buscando Alt + otra clave, tuve que usar e.SystemKey en lugar de e.Key (el valor de e.Key era "Sistema" en el caso de usar alt + otro carácter, en mi caso)
Josh
3

Así es como lo manejo (usando PreviewKeyDown), digamos que estamos buscando Alt + R ...

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

Tal vez alguien pueda aclarar por qué tuve que usar e.SystemKey y no solo e.Key, ¿tal vez debido al modificador? pero esto ha funcionado perfectamente para mí cuando busco modificador + tecla.

Josh
fuente
0

y también:

si My.Computer.Keyboard.ShiftKeyDown entonces ...

My.Computer.Keyboard.CtrlKeyDown

My.Computer.Keyboard.AltKeyDown

Robar
fuente
0

En parte tomando prestado de @Josh, y algo similar a @Krushik, y también haciendo referencia a una pregunta sobre la diferencia entre KeyEventArgs.systemKey y KeyEventArgs.Key (respondiendo por qué Josh tiene que usar SystemKey); en donde, con las teclas modificadoras (como Alt), e.Key devuelve Key.System y, por lo tanto, la clave 'real' está dentro de e.SystemKey.

Una forma de evitar esto es buscar primero la clave 'real' y luego hacer su 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
fuente