2011-05-03 24 views

Respuesta

54
  • KeyDown: sucede cuando la persona presiona una tecla (cuando el teclado detecta por primera vez un dedo en una tecla, esto sucede cuando la tecla es presionada hacia abajo).

  • KeyPress: se produce cuando se presiona una tecla y luego se libera.

  • KeyUp: sucede cuando la llave se libera

Tienes razón en que todos estos eventos se producen cuando se pulsa una tecla y luego puesto en libertad, en el orden que he descrito anteriormente.

+2

Aunque Reggie no preguntó esto, agregué una respuesta a continuación con ideas sobre cuándo usar KeyDown vs KeyUp. –

+3

La descripción de 'KeyPress' es incorrecta. 'KeyPress' ocurre mientras se presiona la tecla, incluso si nunca se lanza. Ver [respuesta de Cody Gray] (http://stackoverflow.com/a/5871430/1219414). – Juan

63

Hmm, no estoy seguro de cuánto controló el MSDN documentation. Se establece el orden en que los tres eventos ocurren con bastante claridad:

eventos clave se presentan en el siguiente orden:

  1. KeyDown
  2. KeyPress
  3. KeyUp

KeyDown se genera tan pronto como el usuario presiona una tecla en el teclado, mientras están s hasta sostenerlo.

KeyPress se establezca para carácter teclas (a diferencia de KeyDown y KeyUp, que también se plantean para las claves no son caracteres) mientras se pulsa la tecla. Este es un evento de "nivel superior" que KeyDown o KeyUp, y como tal, hay diferentes datos disponibles en el EventArgs.

KeyUp se genera después de que el usuario suelta una tecla en el teclado.

Generalmente, debe manejar el evento KeyUp en su aplicación. Las acciones no se deben iniciar en la interfaz de usuario hasta después de el usuario suelta la clave. Y dado que KeyUp es un evento de nivel inferior a KeyPress, siempre tendrá mucha información al alcance de la mano sobre la tecla presionada, e incluso funcionará para manejar claves que no son de carácter.


Lo que hay que tener en cuenta sobre todo de estos eventos, sin embargo, es que sólo son planteados por el control que tiene el foco. Eso significa que si un control de botón en su formulario tiene actualmente el foco, ninguno de los eventos de clave para su formulario se levantará. Esto a menudo es confuso para los programadores nuevos en .NET.La mejor manera de manejar esto es por razones imperiosas de ProcessCmdKey method la forma:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
{ 
    if (keyData == (Keys.Control | Keys.A)) 
    { 
     MessageBox.Show("You pressed Ctrl+A!"); 
    } 
} 
+0

Me pregunto qué tan fácil es encontrar esa información. Me parece que sería útil si hubiera un sitio con un gráfico que muestre el orden de las ocurrencias de eventos para cada control nativo de Windows ... –

+0

O tal vez algún tipo de sitio de agregación de información con un formato de pregunta y respuesta para hacer que dicha información sea fácil ¿accesible? Ir a la documentación original no siempre es la solución ideal ... – weberc2

+0

@Clay No tienen una tabla de este tipo porque el orden de los eventos/mensajes está (en términos generales) sujeto a cambios en cualquier momento. Es un detalle de implementación del control subyacente, por lo que no puede confiar en un orden particular para * todos los mensajes disponibles. Pero algunos mensajes particulares siempre se envían en un orden particular simplemente por su diseño y lo que significan. Por ejemplo, los que he llamado aquí. La documentación de WinForms tiene una explicación bastante buena de esto para los eventos relacionados con las claves, creo. –

2

KeyDown continuación KeyPress continuación KeyUp es el orden que encuentro.

Normalmente desea enganchar KeyDown cuando se trata de una aplicación donde un usuario mantiene presionada una tecla para la entrada de modos múltiples con la modificación del modo de teclas de control, como en una operación de cambio y clic. KeyPress es para la lógica de tipo simple de entrada de tecla, solo para obtener los trazos de tecla. KeyUp se engancha para poner en lógica que se ejecuta después de algo más procesa KeyPress, desea modificar el contenido de un cuadro de edición de texto después de que su lógica principal KeyPress haya tenido efecto. Francamente, no uso KeyUp tanto, pero a veces es la única forma de recibir un mensaje después de que otra persona haya procesado KeyPress y deba verificar/corregir lo que sucedió.

7

He aquí un caso cuando no lo desea utilizar KeyUp:

Usted tiene un cuadro de lista y pulsando la tecla Enter en una fila invoca un diálogo del editor. Problema: si el usuario presiona la tecla Intro en el botón Aceptar del editor, un evento KeyUp (e.KeyCode = Enter) se filtrará a su cuadro de lista, haciendo que el editor se vuelva a abrir. Esto no ocurre si el usuario presiona la barra espaciadora en el botón Aceptar del editor; en ese caso, el evento KeyUp (e.KeyCode = Space) es manejado por el editor antes de que se cierre.

Aquí es una heurística de selección que utilizo:

If I'm handling the Enter key and I need to guard against a case like the one above 
    then I use KeyDown  
Else if I'm handling key combinations (e.g. CTRL+C) 
    then I favor* KeyDown (KeyUp can make these awkward) 
Else if I am allowing press & hold autorepeat 
    then I use KeyDown  
Else 
    I use KeyUp 

* Si la acción es uno que se puede hacer en un producto de uso común, por ejemplo Microsoft Office, como CTRL + A (para 'Seleccionar todo'), imito el comportamiento de Microsoft, ya que es a eso a lo que los usuarios están acostumbrados.

+0

Pensamientos muy útiles Jim. Pero, ¿esto no da como resultado una experiencia inconsistente? Eso podría argumentarse que no debería suceder, porque el diálogo no debería estar actuando hasta el evento clave. Hasta ahora, siempre he utilizado KeyUp (para la tecla Enter) para ser coherente, pero me encontré con su problema de estado. –

+0

En WPF, la "fuga" de la tecla Intro se puede evitar si se maneja en un evento Vista previa, ¿verdad? – Sabuncu

Cuestiones relacionadas