Формы, не отвечающие на события KeyDown - PullRequest
59 голосов
/ 04 июля 2010

Я некоторое время работал над проектом 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?

Ответы [ 3 ]

138 голосов
/ 04 июля 2010

Для вашей формы свойство KeyPreview установлено в значение true?

Свойство Form.KeyPreview

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

http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx

35 голосов
/ 09 декабря 2015

Наиболее распространенный совет для решения этой проблемы в StackOverflow и MSDN 1 , 2 (включая принятый здесь ответ) является быстрым и простым:

KeyDown события запускаются на Form, если его свойство KeyPreview установлено на true

Это подходит для большинства целей, ноэто рискованно по двум причинам:

  1. KeyDown обработчики не видят все ключи .В частности, «вы не можете видеть виды нажатий клавиш, которые используются для навигации. Например, клавиши курсора и клавиши Tab, Escape и Enter для диалогового окна».

  2. Есть несколько различныхспособы перехвата ключевых событий, и все они происходят в последовательности.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. Здесь - статья с более подробной информацией.

19 голосов
/ 04 июля 2010

Попробуйте установить для свойства KeyPreview в форме значение true. Это помогло мне зарегистрировать нажатия клавиш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...