Я использовал событие KeyDown и какой-то простой код, например if (e.KeyCode == Keys.F1)
, для захвата F1 нажимается в форме, НО если в форме есть текстовые поля или если в форме есть некоторые электронные таблицы с Dock Fill, то приведенный выше код становится бесполезным и ничего не делает. Но я хочу что-то сделать, когда пользователь нажимает F1 в этой форме. Итак, как нам зафиксировать конкретное событие нажатия клавиши, такое как F1, во всей форме ... и я не хочу переходить по маршруту, который захватывает KeyDown всех других элементов управления в форме и передает их в форму для обработки. есть ли более чистый способ сделать это?
Как мне захватить Keys.F1 независимо от сфокусированного элемента управления в форме?
Ответы (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?
KeyPreview
использует ориентированную на события архитектуру .NET, в то время как вы просто переопределяете WndProc
, предпочтительный способ выполнения этой задачи в Win3.1 (да, верно, технология 1992 года).
- person Blindy; 10.05.2011
WndProc
(хотя это тоже работает). Платформа вызывает этот метод в подходящее время специально для обработки этих событий. Кроме того, такой способ позволяет вам решить, хотите ли вы, чтобы событие передавалось другим элементам управления или нет.
- person Cody Gray; 10.05.2011
WndProc
, когда uMsg=WM_KEYDOWN
. И так же, как при проверке кодов виртуальных клавиш в Win32 api, вы не знаете, ввел ли пользователь фактический ключ или его измененную версию (среди прочего). Каждому свое, но я был бы осторожнее, какой API я называю хуже.
- person Blindy; 10.05.2011
KeyPreview
- лучшая альтернатива.
- person Cody Gray; 10.05.2011
Установите KeyPreview
формы в значение true. Это гарантирует, что форма сначала получит сообщения о нажатии клавиш, и если вы обработаете их, вы можете установить e.Handled = true
, чтобы они не передавались элементам управления.
Включите KeyPreview
, и каждое нажатие клавиши в форме сначала будет проходить через обработчики ключевых событий.
Другой способ - переопределить функцию ProcessCmdKey http://msdn.microsoft.com/en-us/library/system.windows.forms.control.processcmdkey(v=VS.100).aspx