c# - tutorial - Formularios que no responden a eventos KeyDown
winforms c# (3)
He estado trabajando durante un tiempo en mi proyecto de Windows Forms, y decidí experimentar con los atajos de teclado. Después de leer un poco, pensé que tenía que escribir un controlador de eventos y vincularlo al evento KeyDown del formulario:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.O)
{
MessageBox.Show("Ctrl+Alt+O: magic!");
}
}
Lo hice de la buena manera de abrir el panel Propiedades del diseñador de Visual Studio, y luego hacer doble clic en el evento KeyDown de mi formulario para generar el controlador de eventos Form1_KeyDown
. Pero al probar mi aplicación, el formulario no responde en absoluto al atajo de teclado Ctrl + Alt + O. El diseñador de Visual Studio sí generó el código para vincular el controlador de eventos al formulario:
private void InitializeComponent()
{
// ...
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
// ...
}
Así que intenté agregar una llamada Console.WriteLine()
al controlador para verificar que se estaba llamando, pero tampoco tuve suerte.
Además, traté de establecer un punto de interrupción en la llamada de enlace de eventos (que se muestra arriba) y encontré que el programa alcanza ese punto de interrupción sin problemas. Pero nunca se alcanzan los puntos de interrupción que establecí dentro de la definición del método.
Para asegurarme de estar haciendo los primeros pasos correctamente, intenté repetirlos con:
Una nueva forma en la misma solución.
Mismo problema: el formulario no responde cuando presiono mi atajo de teclado Ctrl + Alt + O y el depurador ni siquiera está entrando en el controlador de eventos.Intenté esto de nuevo y funciona.Una nueva solución WinForms.
Funciona perfectamente: aparece el cuadro de diálogo del mensaje (la llamadaConsole.WriteLine()
también funciona).
Así que estoy bastante perdido aquí. ¿Qué impide que todos los formularios de este proyecto reciban eventos KeyDown?
¿Su formulario tiene la propiedad KeyPreview establecida en verdadero?
Propiedad Form.KeyPreview
Obtiene o establece un valor que indica si el formulario recibirá eventos clave antes de pasar el evento al control que tiene el foco.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
El consejo más común para este problema en y MSDN 1 , 2 (incluida la respuesta aceptada aquí) es rápido y fácil:
KeyDown
eventosKeyDown
se desencadenan en unForm
siempre que su propiedadKeyPreview
esté establecida entrue
Eso es adecuado para la mayoría de los propósitos, pero es arriesgado por dos razones:
KeyDown
manejadoresKeyDown
no ven todas las claves . Específicamente, "no se puede ver el tipo de teclas que se utilizan para la navegación. Al igual que las teclas del cursor y Tab, Escape e Intro para un diálogo".Hay algunas formas diferentes de interceptar eventos clave, y todos ocurren en secuencia.
KeyDown
se manejó el último . Por lo tanto,KeyPreview
no es una buena vista previa, y el evento podría ser silenciado en unas pocas paradas en el camino.
(Crédito a @HansPassant por esos puntos).
En su lugar, anule ProcessCmdKey
en su Form
:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == Keys.Up)
{
// Handle key at form level.
// Do not send event to focused control by returning true.
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
De esta forma, todas las claves son visibles para el método, y el método es el primero en la cola para ver el evento.
Tenga en cuenta que todavía tiene control sobre si los controles enfocados ven el evento KeyDown
. Simplemente devuelva true
para bloquear el evento KeyDown
posterior, en lugar de establecer KeyPressEventArgs.Handled
en true
como lo haría en un controlador de eventos KeyDown
. Here hay un artículo con más detalles.
Intente establecer la propiedad KeyPreview
en su formulario en verdadero. Esto funcionó para registrar las pulsaciones de teclas.