Как мне захватить Keys.F1 независимо от сфокусированного элемента управления в форме?

Я использовал событие KeyDown и какой-то простой код, например if (e.KeyCode == Keys.F1), для захвата F1 нажимается в форме, НО если в форме есть текстовые поля или если в форме есть некоторые электронные таблицы с Dock Fill, то приведенный выше код становится бесполезным и ничего не делает. Но я хочу что-то сделать, когда пользователь нажимает F1 в этой форме. Итак, как нам зафиксировать конкретное событие нажатия клавиши, такое как F1, во всей форме ... и я не хочу переходить по маршруту, который захватывает KeyDown всех других элементов управления в форме и передает их в форму для обработки. есть ли более чистый способ сделать это?


person Bohn    schedule 10.05.2011    source источник


Ответы (4)


Да, действительно есть. Правильный способ для формы обрабатывать ключевые события независимо от элемента управления, который в настоящее время имеет фокус ввода, - это переопределить _ 1_ метод вашего класса формы:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
    if (keyData == Keys.F1)
    {
        MessageBox.Show("You pressed the F1 key");
        return true;    // indicate that you handled this keystroke
    }

    // Call the base class
    return base.ProcessCmdKey(ref msg, keyData);
}

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

И вам лучше игнорировать свойство KeyPreview . Это анахронизм из 6 дней VB и не совсем предпочтительный способ сделать это в мире .NET. Дополнительная литература: Недостаток установки Form.KeyPreview = true?

person Cody Gray    schedule 10.05.2011
comment
Как это не лучший способ? KeyPreview использует ориентированную на события архитектуру .NET, в то время как вы просто переопределяете WndProc, предпочтительный способ выполнения этой задачи в Win3.1 (да, верно, технология 1992 года). - person Blindy; 10.05.2011
comment
@Blindy: Идиоматический способ делать что-то в мире Windows API не сильно изменился с первых дней Windows. И это не в точности то же самое, что переопределение WndProc (хотя это тоже работает). Платформа вызывает этот метод в подходящее время специально для обработки этих событий. Кроме того, такой способ позволяет вам решить, хотите ли вы, чтобы событие передавалось другим элементам управления или нет. - person Cody Gray; 10.05.2011
comment
На самом деле это то же самое, что переопределить WndProc, когда uMsg=WM_KEYDOWN. И так же, как при проверке кодов виртуальных клавиш в Win32 api, вы не знаете, ввел ли пользователь фактический ключ или его измененную версию (среди прочего). Каждому свое, но я был бы осторожнее, какой API я называю хуже. - person Blindy; 10.05.2011
comment
@Blindy: Функционально? Или идиоматически? Я не придираюсь к функциям - я уже сказал, что это тоже работает. Но я категорически не согласен с тем, что KeyPreview - лучшая альтернатива. - person Cody Gray; 10.05.2011

Установите KeyPreview формы в значение true. Это гарантирует, что форма сначала получит сообщения о нажатии клавиш, и если вы обработаете их, вы можете установить e.Handled = true, чтобы они не передавались элементам управления.

person Bala R    schedule 10.05.2011

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

person Blindy    schedule 10.05.2011

Другой способ - переопределить функцию ProcessCmdKey http://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey(v=VS.100).aspx

person JTorrecilla    schedule 10.05.2011