Come gestire i messaggi di input della tastiera nel modulo

Windows Form consente di gestire i messaggi da tastiera a livello di modulo, prima che i messaggi raggiungano un controllo. Questo articolo illustra come eseguire questa attività.

Gestire un messaggio da tastiera

Gestisci l'evento KeyPress o KeyDown della maschera attiva e imposta la proprietà KeyPreview della maschera su true. Questa proprietà fa sì che l'input della tastiera raggiunga il modulo prima che raggiunga tutti i controlli del modulo. Nell'esempio di codice seguente viene gestito l'evento di KeyPress rilevando tutte le chiavi numerice e utilizzando 1, 4e 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

Quando KeyPreview non è sufficiente

L'impostazione Form.KeyPreview = true non garantisce che ogni chiave raggiunga i gestori eventi a livello di modulo. Alcuni tasti vengono preelaborati prima dell'esecuzione dei normali eventi del modulo. Comprendere queste eccezioni è importante per gestire correttamente i tasti di comando, i tasti di dialogo e l'input specifico del controllo.

Preelaborazione dei tasti di comando e di dialogo

Prima dell'attivazione degli eventi della tastiera a livello di modulo, Windows pre-elabora determinati tasti tramite questi metodi (in ordine):

  1. ProcessCmdKey: intercetta i tasti di comando, ad esempio i tasti di scelta rapida e gli acceleratori di menu. Se questo metodo restituisce true, la chiave viene consumata e non viene generato alcun evento.
  2. IsInputKey: determina se una chiave deve generare un KeyDown evento o passare a ProcessDialogKey.
  3. ProcessDialogKey: gestisce i tasti di navigazione (Escape, Tab, Invio e tasti freccia). Se viene elaborato, non viene generato alcun evento.

Se un controllo con stato attivo utilizza una chiave durante la pre-elaborazione, il form non lo riceve mai, indipendentemente da KeyPreview.

Casi speciali che ignorano i gestori a livello di modulo

  • Invio e escape: queste chiavi possono essere gestite da AcceptButton e CancelButton prima di raggiungere gli eventi del modulo.
  • Tab: spesso viene intercettato dalla gestione del focus dei controlli e non raggiunge i gestori del modulo.
  • Scelte rapide da menu: le combinazioni di tasti ALT vengono gestite dalla pre-elaborazione dei menu.

Intercetta i tasti di comando a livello di modulo

Per gestire i tasti di comando (inclusi i tasti di scelta rapida dei menu e i tasti di dialogo) a livello di modulo, eseguire l'override ProcessCmdKey del modulo. Questa operazione viene eseguita durante la pre-elaborazione, prima degli eventi di modulo standard.

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

Per i tasti che devono generare eventi standard in un controllo specifico, usare PreviewKeyDown con IsInputKey impostato su true su tale controllo.

Vedere anche