He visto una serie de respuestas que sugieren el uso de Keyboard.Modifiers
para determinar si un evento KeyDown
es para una clave que tiene un conjunto de modificadores. Desafortunadamente, dado que Keyboard.Modifiers
devuelve el estado actual de los modificadores (en lugar del estado del modificador cuando se presionó la tecla), esto resulta en un error intermitente realmente molesto para los mecanógrafos rápidos.¿Cómo recuperar correctamente las teclas modificadoras en un evento WPF KeyDown?
Específicamente, imagine que alguien presiona Ctrl + A, y suelta Ctrl solo unos pocos milisegundos después de presionar A. Ahora imagine que el sistema estaba bajo mucha carga; el manejador de claves comenzó a ejecutarse, pero se adelantó durante 50 ms. En el momento en que el controlador de clave se está ejecutando de nuevo, el estado actual de Ctrl se "libera". El controlador de teclas ahora pensará que se presionó "A" sin Ctrl, y esto es malo.
Del mismo modo, si un mecanógrafo rápido entra A, Ctrl + Fin y mi aplicación utiliza Keyboard.Modifiers
, en su lugar podría terminar observando Ctrl + A ...
En WinForms, el evento KeyDown
me dice que el estado de Ctrl exactamente, incluso si ya se ha liberado cuando se procesa el evento. ¿Cómo puedo obtener este mismo comportamiento en WPF?
Editar: es posible que Keyboard.Modifiers en realidad no recupere las teclas modificadoras "actuales", sino las teclas modificadoras relacionadas con el mensaje de reducción de teclas que se está procesando actualmente. En WinAPI, esta fue la distinción entre funciones de estado de la tecla "asíncrona" y no asíncrona. Desafortunadamente, the documentation no menciona qué significa exactamente "actual". Si alguien sabe, por favor dígalo.
¿estás seguro? no encuentro ninguna pista sobre msdn, eso probará su teoría ... sería realmente extraño, que los argumentos del controlador no incluyan las teclas ORIGINALMENTE presionadas ... si se une a "onkeyDown" y el usuario presiona CONTROL (mantener) y luego a, luego suelta CONTROL, ¡el evento se disparará 2 veces! primero con "Control" solamente, luego con CONTROL + A ... un poco extraño - en mi humilde opinión, que podría darse cuenta de eso fácilmente con Thread.Sleep ... ¿Tengo que arrancar VS ¿ahora mismo? ;) – TheHe
@TheHe Los argumentos del manejador incluyen la _key_ presionada originalmente, pero no la información de la tecla modificadora. En el viejo y viejo WinAPI, las claves modificadoras se pasan junto con el mensaje. Lo mismo sucede en WinForms. La documentación en realidad le advierte que no intente procesar el estado _current_; por ejemplo, si la aplicación no responde por alguna razón (por ejemplo, agolpamiento de HDD), el manejador puede invocarse _segundos_ después del hecho. –