Язык

Обработка входных сообщений клавиатуры в форме

Windows Forms предоставляет возможность обрабатывать сообщения клавиатуры на уровне формы, прежде чем сообщения достигают элемента управления. В этой статье показано, как выполнить эту задачу.

Обработка сообщения клавиатуры

Обработайте событие KeyPress или KeyDown активной формы и задайте для свойства KeyPreview формы значение true. Это свойство приводит к тому, что ввод с клавиатуры поступает в форму прежде, чем он поступит к любым элементам управления на ней. Следующий пример кода обрабатывает событие KeyPress путем обнаружения всех цифровых клавиш и поглощения 1, 4и 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

Когда KeyPreview недостаточно

Параметр Form.KeyPreview = true не гарантирует, что каждый ключ достигает обработчиков событий уровня формы. Некоторые ключи проходят предварительную обработку до выполнения стандартных событий формы. Понимание этих исключений важно для правильной обработки клавиш команд, диалоговых ключей и входных данных, относящихся к элементу управления.

Предварительная обработка командных и диалоговых клавиш

Перед запуском событий клавиатуры на уровне формы Windows предварительно обрабатывает определенные ключи с помощью этих методов (в порядке):

  1. ProcessCmdKey: перехватывает такие управляющие клавиши, как сочетания клавиш для вызова меню и акселераторы. Если этот метод возвращает true, клавиша считается обработанной, и событие не возникает.
  2. IsInputKey: определяет, должна ли клавиша вызывать событие KeyDown event или переходить к ProcessDialogKey.
  3. ProcessDialogKey: обрабатывает клавиши навигации (Esc, Tab, Enter и клавиши со стрелками). При обработке событие не возникает.

Если элемент управления, находящийся в фокусе, перехватывает нажатие клавиши на этапе предварительной обработки, форма никогда его не получает, независимо от KeyPreview.

Особые случаи обхода обработчиков уровня формы

  • Enter и Escape: эти клавиши могут обрабатываться AcceptButton и CancelButton до того, как они дойдут до событий формы.
  • Tab: Часто перехватывается механизмом управления фокусом элементов управления и не доходит до обработчиков формы.
  • Сочетания клавиш в меню: сочетания клавиш ALT обрабатываются предварительной обработкой меню.

Перехват командных клавиш на уровне формы

Чтобы обрабатывать командные клавиши (включая сочетания клавиш меню и диалоговых окон) на уровне формы, переопределите метод ProcessCmdKey в своей форме. Это выполняется во время предварительной обработки до стандартных событий формы.

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

Для клавиш, которые должны вызывать стандартные события в определенном элементе управления, используйте PreviewKeyDown с IsInputKey, установленным в значение true, для этого элемента управления.

См. также