¿Cuál es la diferencia entre KeyDown y KeyPress en .NET?

185

¿Cuál es la diferencia entre los eventos KeyDowny KeyPressen .net?

Josh Kodroff
fuente

Respuestas:

308

Aparentemente hay muchos malentendidos sobre esto.

La única diferencia práctica entre KeyDowny KeyPresses que KeyPresstransmite el carácter resultante de una pulsación de tecla, y solo se llama si hay una.

En otras palabras, si presiona Asu teclado, obtendrá esta secuencia de eventos:

  1. KeyDown: KeyCode = Keys.A, KeyData = Keys.A, Modifiers = Keys.None
  2. KeyPress: KeyChar = 'a'
  3. KeyUp: KeyCode = Keys.A

Pero si presiona Shift+ A, obtendrá:

  1. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  2. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  3. KeyPress: KeyChar = 'A'
  4. KeyUp: KeyCode = Keys.A
  5. KeyUp: KeyCode = Keys.ShiftKey

Si mantiene presionadas las teclas por un tiempo, obtendrá algo como:

  1. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  2. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  3. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  4. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  5. KeyDown: KeyCode = Keys.ShiftKey, KeyData = Keys.ShiftKey, Shift, Modifiers = Keys.Shift
  6. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  7. KeyPress: KeyChar = 'A'
  8. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  9. KeyPress: KeyChar = 'A'
  10. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  11. KeyPress: KeyChar = 'A'
  12. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  13. KeyPress: KeyChar = 'A'
  14. KeyDown: KeyCode = Keys.A, KeyData = Keys.A | Keys.Shift, Modificadores = Keys.Shift
  15. KeyPress: KeyChar = 'A'
  16. KeyUp: KeyCode = Keys.A
  17. KeyUp: KeyCode = Keys.ShiftKey

Tenga en cuenta que KeyPressse produce en el medio KeyDown y KeyUp, no después KeyUp, como muchas de las otras respuestas han dicho, que KeyPressno se llama cuando no se genera un carácter, y que KeyDownse repite mientras la tecla se mantiene pulsada, también contrario a muchas de las otras respuestas .

Ejemplos de claves que no resultan directamente en llamadas a KeyPress:

  • Shift` Ctrl`Alt
  • F1 mediante F12
  • Teclas de flecha

Ejemplos de teclas que hacen resultado en llamadas a KeyPress:

  • Aa través Z, a 0través 9, etc.
  • Spacebar
  • Tab (KeyChar = '\ t', ASCII 9)
  • Enter (KeyChar = '\ r', ASCII 13)
  • Esc (KeyChar = '\ x1b', ASCII 27)
  • Backspace (KeyChar = '\ b', ASCII 8)

Para los curiosos, KeyDownse correlaciona aproximadamente con WM_KEYDOWN, KeyPresscon WM_CHARy KeyUpcon WM_KEYUP. WM_KEYDOWN se puede llamar menos que el número de repeticiones de teclas, pero envía un recuento de repetición, que, IIRC, WinForms utiliza para generar exactamente un KeyDown por repetición.

Papi
fuente
2
Excelente explicación, gracias, una advertencia, sin embargo, Escape no activa KeyPress en Chrome (no estoy seguro acerca de los demás).
Barney
3
@BarnabasSzabolcs: ¿Chrome ejecuta .NET?
P papá el
@PDaddy ups, lo he pasado por alto, pensé que era javascript: D pero con un estilo un poco extraño: P, sin embargo, parece que las reglas son bastante similares: DD ... curiosamente esta respuesta me ayudó mucho de todos modos ... . salud :)
Barney
@PDaddy Sé que al menos Tab no activa KeyDown o KeyUp por defecto
PsychoData
@PsychoData: Esto se debe a que la tecla Tab cambia de foco, por lo que no se procesa como entrada. Si anula ProcessDialogKeyy devuelve falso cuando keyDataes Keys.Tabo Keys.Shift | Keys.Tab, verá la tecla Tab en la tecla (On) (Abajo | Presione | Arriba).
P Daddy
73

El evento KeyPress no se genera mediante teclas que no son caracteres; sin embargo, las claves que no son caracteres generan los eventos KeyDown y KeyUp.

http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress.aspx

Jon Spokes
fuente
17
La mayoría de las otras respuestas son incorrectas de una forma u otra, pero esta se acerca más a la realidad. KeyPress se genera solo para las teclas de caracteres y obedece a la configuración de los retrasos / repetición de escritura del teclado. La secuencia real de eventos es: 1) KeyDown 2) para la tecla de caracteres KeyPress una o más veces (dependiendo de la configuración del sistema y cuánto tiempo se mantenga presionada la tecla) 3) KeyUp
Filip Navara
No tengo el representante para hacerlo, pero ¿alguien podría reventar un wiki y combinar el contenido del comentario anterior y la respuesta aceptada?
Josh Kodroff
11
El comentario de Filip Navara no es del todo correcto. Si se mantiene presionada una tecla, obtendrá KeyDown, KeyPress, KeyDown, KeyPress, KeyDown, KeyPress KeyUp. KeyDown se llama para cada repetición.
P Daddy
9

KeyPress solo se activa con caracteres imprimibles y se activa después del evento KeyDown. Dependiendo de la configuración de retraso de escritura, puede haber múltiples eventos KeyDown y KeyPress, pero solo un evento KeyUp.

KeyDown
KeyPress
KeyUp

stevehipwell
fuente
Estás cerca, pero fuera de la secuencia.
P Daddy
@P Daddy: lo he corregido, debería haberlo revisado antes de pasar de memoria.
stevehipwell
@ Stevo3000, para su información: los caracteres Unicode no imprimibles también activarán los eventos de KeyPress. Tengo una aplicación que lee datos insertados por un lector de código de barras en un cuadro de texto y el lector incluye caracteres unicode no imprimibles.
Jeff LaFay
@jlafay: no según MSDN El evento KeyPress no se genera mediante teclas que no son caracteres; sin embargo, las claves que no son caracteres generan los eventos KeyDown y KeyUp.
stevehipwell
@ Stevo3000, no estoy seguro de cómo el escáner de código de barras ingresa el texto en un cuadro de texto, pero KeyPress activa los caracteres especiales que envía. El valor comienza con un carácter no imprimible y termina con un carácter no imprimible. Así que no estoy seguro de cómo se dispara si eso es cierto. Tal vez eche un vistazo al ensamblado .Net que contiene los eventos con IL Spy para ver mejor lo que realmente se detecta.
Jeff LaFay
5

KeyPress es un nivel de abstracción más alto que KeyDown (y KeyUp). KeyDown y KeyUp están relacionados con el hardware: la acción real de una tecla en el teclado. KeyPress es más "Recibí un personaje del teclado".

Jeff Hornby
fuente
4

De MSDN:

Los eventos clave ocurren en el siguiente orden:

  1. KeyDown

  2. KeyPress

  3. Tecla Arriba

Además, KeyPress le da la oportunidad de declarar la acción como " manejada " para evitar que haga algo.

Jon B
fuente
FYI, KeyDown y KeyUp también tienen una propiedad Handled que puede configurar para que no se encuentre entre KeyPress y los otros eventos clave.
Jeff LaFay
FWIW, aunque KeyUp, como KeyDown, obtiene un parámetro KeyEventArgs, su Handledpropiedad no funciona para KeyUp ( SuppressKeyPresstampoco lo es).
JonP
3

Keydown está presionando la tecla sin soltarla, Keypress es un ciclo completo de presionar y soltar.

Dicho de otra manera, KeyDown + KeyUp = Keypress

Rob Cowell
fuente
3
según MSDN, la secuencia de eventos es KeyDown, KeyPress, KeyUp ( msdn.microsoft.com/en-us/library/… )
Nathan Koop
@RobCowell Además, como señaló jlafay, KeyPress no depende en absoluto de KeyDown o KeyUp.
PsychoData
1

Del desarrollador de blogs :

Para comprender la diferencia entre presionar tecla y presionar tecla, es útil comprender la diferencia entre un "carácter" y una "tecla" . Una "tecla" es un botón físico en el teclado de la computadora, mientras que un "carácter" es un símbolo escrito presionando un botón. En teoría, los eventos keydown y keyup representan teclas presionadas o liberadas, mientras que el evento keypress representa un carácter que se está escribiendo. La implementación de la teoría no es la misma en todos los navegadores.

Nota: También puede probar el Probador de eventos clave (disponible en el sitio mencionado anteriormente) para comprender este concepto.

Abdul Latheef Mohamed
fuente
1

KEYUP se capturará solo una vez, al soltar la tecla presionada, independientemente de cuánto tiempo se mantenga presionada la tecla, por lo que si desea capturar dicha tecla solo una vez, KEYUP es el evento adecuado para capturar.

Michael Haephrati
fuente
El KeyPressevento se genera para cada carácter generado a partir de la entrada, tanto en respuesta a las pulsaciones de teclas físicas como cuando el carácter es el resultado de la función de repetición automática. Cómo funciona la entrada de teclado documenta este comportamiento.
Inspectable el
Tienes razón. Actualizaré mi respuesta. La respuesta correcta es usar KEYUP, que se activará una vez, al soltar uno o más golpes de tecla.
Michael Haephrati
Aunque ya no está mal, todavía no responde la pregunta que se hizo. Esto no es útil.
Inspectable el
0

La explicación más fácil:

Mantuve presionada la tecla 'd' por un segundo y luego la solté.

dddddd

el evento keydown ocurrió una vez antes de que apareciera la primera d en la pantalla, el evento keypress ocurrió 6 veces y el evento keyup ocurrió después de que apareciera la última d en la pantalla.


fuente
maldita sea, leí mal la pregunta y me la metí en la cabeza que quería decir javascript