Захват функциональной клавиши на уровне формы без конфликта пунктов меню

Я разработал приложение Windows Forms (.NET 4.6, VS.2017), и у меня есть две формы: основная и немодальная. В обеих формах мне нужно поймать пользователя, нажимающего клавишу F2. Кстати, это единственная функциональная клавиша, используемая приложением, никакое другое сочетание клавиш не определено ни для какой другой функциональной клавиши.

В обеих формах я включил Form.KeyPreview, что по умолчанию равно false. Затем я также реализовал событие KeyDown и в нем проверяю, является ли это моей функциональной клавишей:

private void myView_KeyDown(object sender, KeyEventArgs e)
{
   if (e.KeyCode == Keys.F2)  // breakpoint placed here!
   {
        // perform action
        e.Handled = true;
   }
}

Обратите внимание, что я поместил точку останова на оператор IF, проверяющий, какая клавиша была нажата, а не внутри блока действий.

Теперь в моей немодальной форме это работает абсолютно нормально, независимо от того, какую функциональную клавишу я выбираю.

Однако основная форма демонстрирует странное поведение с тем же кодом. Если в основной форме я использую «e.KeyCode == Keys.F3», то точка останова срабатывает для всех других нажатых функциональных клавиш, КРОМЕ F3.

Итак, затем я изменил оператор if, чтобы вместо этого проверять F2, а не F3. Но теперь с этим изменением точка останова срабатывает для всех функциональных клавиш, кроме F2, поэтому F3, которая раньше не работала (при проверке F3), теперь работает, а F2 — нет.

Неважно, какую функциональную клавишу я выбрал, точка останова сработает для ВСЕХ функциональных клавиш, КРОМЕ той, которую я выбрал.

Вот в чем загвоздка... В одном из моих элементов ToolStripMenuItems я также поместил ту же функциональную клавишу в качестве ярлыка, потому что они выполняют одно и то же действие (тогда пользователю не нужно нажимать Alt G, а затем Alt что-то еще, а вместо этого использовать F2 напрямую.

Итак, если я удалю ярлык из ToolStripMenuItem, моя форма KeyDown будет работать, как и ожидалось, НО тогда у пользователя нет визуального намека на то, что он может использовать F2 для выполнения этой функции. Странно здесь еще и то, что ни пункт меню toolstrip, ни форма не реагируют на выбранную функциональную клавишу.

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


person Lord of Scripts    schedule 21.07.2017    source источник
comment
Помимо того, что точка останова срабатывает или нет, в чем проблема? Оптимизация компиляции может привести к тому, что вы наблюдаете, и я бы не беспокоился об этом, если только нет реальной проблемы.   -  person Guillaume CR    schedule 21.07.2017
comment
Проблема в том, что я хочу иметь ярлык как для элемента меню панели инструментов, так и для ввода с клавиатуры, потому что в обоих случаях F2 должен выполнять ОДНУ функцию. Но похоже, что он не может обрабатывать оба типа   -  person Lord of Scripts    schedule 25.07.2017
comment
Почему вы используете событие KeyDown и KeyPreview? Настройка клавиш быстрого доступа, кажется, обеспечивает желаемое поведение.   -  person Guillaume CR    schedule 25.07.2017
comment
Я хочу иметь возможность просто нажимать F2 в любом месте формы, а не только во время фокусировки на кнопке или элементе меню панели инструментов. Я могу удалить его из элементов и просто оставить в форме, но тогда мне придется добавить метку или что-то подобное, чтобы сообщить пользователю, что он может использовать F2 для этой цели. Именно по этой причине его также назвали ярлыком.   -  person Lord of Scripts    schedule 27.07.2017
comment
Установка свойства ShortCutKeys элемента MenuStripItem позволяет пользователю в любой момент нажать клавишу F2. Вам не нужно фокусировать предмет или полосу для работы F2. Вы испытываете поведение, отличное от моего?   -  person Guillaume CR    schedule 28.07.2017


Ответы (1)


После тестирования, установив для свойства ShortcutKeys MenuStripITem значение «F2», я смог получить указанное вами поведение. Щелчок по пункту меню или нажатие F2 выполняли код обработчика кнопки. Я не менял свойство KeyPreview и не реализовывал KeyDown. Думаю избавление от этого ненужного кода вам поможет.

person Guillaume CR    schedule 25.07.2017