Некоторое время я работал над своим проектом Windows Forms и решил поэкспериментировать с сочетаниями клавиш. После небольшого чтения я решил, что мне нужно просто написать обработчик событий и привязать его к событию KeyDown формы:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.O)
{
MessageBox.Show("Ctrl+Alt+O: magic!");
}
}
Я сделал это старым добрым способом, открыв панель свойств дизайнера Visual Studio, а затем дважды щелкнув событие KeyDown в моей форме, чтобы сгенерировать Form1_KeyDown
обработчик событий. Но при тестировании моего приложения форма вообще не реагирует на сочетание клавиш Ctrl+ Alt+ O. Однако дизайнер Visual Studio сгенерировал код для привязки обработчика событий к форме:
private void InitializeComponent()
{
// ...
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
// ...
}
Поэтому я попытался добавить Console.WriteLine()
вызов обработчику, чтобы проверить, что он вообще вызывается, но и в этом не повезло.
Кроме того, я попытался установить точку останова для вызова привязки события (показанный чуть выше) и обнаружил, что программа без проблем достигает этой точки останова. Но любые точки останова, которые я установил в самом определении метода, никогда не достигаются.
Чтобы убедиться, что первые несколько шагов я делаю правильно, я попытался повторить их:
Новая форма в том же растворе.
Та же проблема: форма не отвечает, когда я нажимаю Ctrl комбинацию клавиш + Alt+, Oа отладчик даже не входит в обработчик событий.Попробовал еще раз, и он работает.Совершенно новое решение WinForms.
Работает отлично: появляется диалог сообщения (Console.WriteLine()
звонок тоже работает).
Так что я совершенно потерялся здесь. Что мешает всем формам в этом одном проекте получать события KeyDown?
Самый распространенный совет по решению этой проблемы в StackOverflow и MSDN 1 , 2 (включая принятый здесь ответ) - быстрый и простой:
Этого достаточно для большинства целей, но это рискованно по двум причинам:
KeyDown
обработчики не видят все ключи . В частности, «вы не можете видеть, какие нажатия клавиш используются для навигации. Например, клавиши курсора и Tab, Escape и Enter для диалогового окна».Есть несколько различных способов перехвата ключевых событий, и все они происходят последовательно.
KeyDown
обрабатывается в последнюю очередь . Следовательно,KeyPreview
это не так уж и много для предварительного просмотра, и событие можно было бы отключить на нескольких остановках по пути.(Благодарим @HansPassant за эти баллы.)
Вместо этого переопределите
ProcessCmdKey
в своемForm
:protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.Up) { // Handle key at form level. // Do not send event to focused control by returning true. return true; } return base.ProcessCmdKey(ref msg, keyData); }
Таким образом, все ключи будут видны методу, и метод будет первым в очереди, чтобы увидеть событие.
Обратите внимание, что вы по-прежнему можете контролировать, видят ли
KeyDown
событие сфокусированные элементы управления . Просто вернуться ,true
чтобы блокировать последующееKeyDown
событие, а не устанавливать ,KeyPressEventArgs.Handled
чтобы ,true
как вы бы вKeyDown
обработчик событий. Вот статья с более подробной информацией.источник
Попробуйте установить для
KeyPreview
свойства в вашей форме значение true. Это сработало для меня для регистрации нажатий клавиш.источник