Наиболее распространенный совет по этой проблеме в StackOverflow и MSDN 1 , 2 (включая принятый ответ здесь) является быстрым и легким:
События
KeyDown
запускаются наForm
, пока его свойствоKeyPreview
установлено наtrue
. Это подходит для большинства целей, но это рискованно по двум причинам:
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
. Здесь - статья с более подробной информацией.
Согласно документации :
В объявлении поля readonly
указывает, что присвоение полю может происходить только как часть объявления или в конструкторе в того же класса.
Вы делаете это точно, присваивая внутри конструктора.
Сам список является readonly
, а не его содержание.