Cómo controlar los mensajes de entrada del teclado en el formulario

Windows Forms proporciona la capacidad de controlar los mensajes de teclado en el nivel de formulario, antes de que los mensajes lleguen a un control. En este artículo se muestra cómo realizar esta tarea.

Control de un mensaje de teclado

Encargarse del evento KeyPress o KeyDown del formulario activo y establecer la propiedad KeyPreview del formulario a true. Esta propiedad hace que la entrada del teclado llegue al formulario antes de que llegue a los controles del formulario. En el ejemplo de código siguiente se controla el KeyPress evento detectando todas las teclas numéricas y consumiendo 1, 4 y 7.

// Detect all numeric characters at the form level and consume 1, 4, and 7.
// Form.KeyPreview must be set to true for this event handler to be called.
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
    if (char.IsDigit(e.KeyChar))
    {
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.");

        switch (e.KeyChar)
        {
            case '1':
            case '4':
            case '7':
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.");
                e.Handled = true;
                break;
        }
    }
}
' Detect all numeric characters at the form level and consume 1, 4, and 7.
' Form.KeyPreview must be set to true for this event handler to be called.
Private Sub Form1_KeyPress(sender As Object, e As KeyPressEventArgs)
    If Char.IsDigit(e.KeyChar) Then
        MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' pressed.")

        Select Case e.KeyChar
            Case "1"c, "4"c, "7"c
                MessageBox.Show($"Form.KeyPress: '{e.KeyChar}' consumed.")
                e.Handled = True
        End Select
    End If

End Sub

Cuando KeyPreview no es suficiente

La configuración Form.KeyPreview = true no garantiza que cada clave alcance los controladores de eventos de nivel de formulario. Algunas claves pasan por el preprocesamiento antes de que se ejecuten eventos de formulario estándar. Comprender estas excepciones es importante para controlar correctamente las claves de comando, las teclas de diálogo y la entrada específica del control.

Preprocesamiento de teclas de comando y cuadro de diálogo

Antes de que se activen los eventos de teclado de nivel de formulario, Windows preprocesa determinadas teclas a través de estos métodos (en orden):

  1. ProcessCmdKey: Intercepta teclas de control, como los atajos de menú y los aceleradores. Si este método devuelve true, la clave se consume y no se activa ningún evento.
  2. IsInputKey: determina si una clave debe generar un KeyDown evento o ir a ProcessDialogKey.
  3. ProcessDialogKey: controla las teclas de navegación (Teclas de escape, Tabulación, Retorno y teclas de dirección). Si se procesa, no se desencadena ningún evento.

Si un control centrado consume una clave durante el preprocesamiento, el formulario nunca lo recibe, independientemente de KeyPreview.

Casos especiales que eluden los controladores a nivel de formulario

  • Entrar y escape: estas claves pueden controlarse mediante AcceptButton y CancelButton antes de llegar a eventos de formulario.
  • Tab: A menudo se consume mediante la administración del foco del control y no llega a los controladores del formulario.
  • Métodos abreviados de menú: las combinaciones de teclas alt se controlan mediante el preprocesamiento del menú.

Interceptar claves de comando a nivel de formulario

Para controlar las teclas de comando (incluidos los métodos abreviados de menú y las teclas de diálogo) en el nivel de formulario, invalide ProcessCmdKey en el formulario. Esto se ejecuta durante el preprocesamiento, antes de los eventos de formulario estándar.

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    // Intercept Ctrl+A for custom handling
    if (keyData == (Keys.Control | Keys.A))
    {
        MessageBox.Show("Ctrl+A intercepted at form level");
        return true; // Mark as handled
    }

    // Pass other keys to the base handler
    return base.ProcessCmdKey(ref msg, keyData);
}
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
    ' Intercept Ctrl+A for custom handling
    If keyData = (Keys.Control Or Keys.A) Then
        MessageBox.Show("Ctrl+A intercepted at form level")
        Return True ' Mark as handled
    End If

    ' Pass other keys to the base handler
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

Para las claves que deben generar eventos estándar en un control específico, utilice PreviewKeyDown con IsInputKey establecido en true en ese control.

Consulte también