Клавиши со стрелками вверх, вниз, влево и вправо не вызывают событие KeyDown
Я создаю приложение, в котором все ключевые входные данные должны обрабатываться самими окнами.
Я установил tabstop в false для каждого элемента управления ведьма может захватить фокус, кроме панели (но я не знаю, если это имеет эффект).
Я установил KeyPreview в true, и я обрабатываю событие KeyDown в этой форме.
моя проблема в том, что иногда клавиши со стрелками больше не реагируют:
событие keydown не запускается при нажатии только клавиша со стрелкой.
событие keydown запускается, если я нажимаю клавишу со стрелкой с модификатором управления.
У вас есть идея, почему моя клавиша со стрелкой внезапно перестает стрелять?
9 ответов:
protected override bool IsInputKey(Keys keyData) { switch (keyData) { case Keys.Right: case Keys.Left: case Keys.Up: case Keys.Down: return true; case Keys.Shift | Keys.Right: case Keys.Shift | Keys.Left: case Keys.Shift | Keys.Up: case Keys.Shift | Keys.Down: return true; } return base.IsInputKey(keyData); } protected override void OnKeyDown(KeyEventArgs e) { base.OnKeyDown(e); switch (e.KeyCode) { case Keys.Left: case Keys.Right: case Keys.Up: case Keys.Down: if (e.Shift) { } else { } break; } }
у меня была точно такая же проблема. Я рассмотрел предоставленный ответ @Snarfblam; однако, если Вы читаете документацию по MSDN, метод ProcessCMDKey предназначен для переопределения ключевых событий для элементов меню в приложении.
недавно я наткнулся на эту статью от microsoft, которая выглядит довольно многообещающе: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx. по мнению microsoft, лучше всего сделать это установить
e.IsInputKey=true;
наPreviewKeyDown
событие после обнаружения стрелки. Это приведет к увольнениюKeyDown
событие.это работало довольно хорошо для меня и было меньше взлома, чем переопределение ProcessCMDKey.
Я использую PreviewKeyDown
private void _calendar_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e){ switch (e.KeyCode){ case Keys.Down: case Keys.Right: //action break; case Keys.Up: case Keys.Left: //action break; } }
посмотреть ответ Родольфо Нойбера для лучшего ответа
(мой оригинальный ответ):
производные от класса управления, и вы можете переопределить метод ProcessCmdKey. Microsoft решила опустить эти ключи из событий KeyDown, потому что они влияют на несколько элементов управления и перемещают фокус, но это очень затрудняет реакцию приложения на эти ключи любым другим способом.
к сожалению, это довольно трудно сделать с помощью клавиш со стрелками, из-за ограничений в событиях KeyDown. Однако, есть несколько способов обойти это:
- как заявил @Snarfblam, вы можно переопределить метод ProcessCmdKey, который сохраняет возможность разбора нажатия клавиш со стрелками.
- как принятый ответ из этого вопроса состояния, XNA имеет встроенный метод под названием клавиатура.GetState(), которым позволяет использовать вводы со стрелками. Однако WinForms не имеет этого, но Это можно сделать через P / Invoke или by используя класс, который помогает с ним.
Я рекомендую попробовать использовать этот класс. Это довольно просто сделать так:
var left = KeyboardInfo.GetKeyState(Keys.Left); var right = KeyboardInfo.GetKeyState(Keys.Right); var up = KeyboardInfo.GetKeyState(Keys.Up); var down = KeyboardInfo.GetKeyState(Keys.Down); if (left.IsPressed) { //do something... } //etc...
Если вы используете это в сочетании с событием KeyDown, я думаю, что вы можете надежно достичь своей цели.
у меня была аналогичная проблема при вызове окна WPF из WinForms.
var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); ElementHost.EnableModelessKeyboardInterop(wpfwindow); wpfwindow.Show();
однако, показывая окно как
для захвата нажатий клавиш в элементе управления Forms необходимо создать новый класс, основанный на классе нужного элемента управления, и переопределить ProcessCmdKey().
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { //handle your keys here }
пример :
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { //capture up arrow key if (keyData == Keys.Up ) { MessageBox.Show("You pressed Up arrow key"); return true; } return base.ProcessCmdKey(ref msg, keyData); }
полный источник...клавиши со стрелками в C#
Вейн
лучший способ сделать, я думаю, это справиться с этим, как сказал MSDN http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx
но справиться с этим, как вам это действительно нужно. Мой способ (в примере ниже) - поймать каждый KeyDown ; -)
/// <summary> /// onPreviewKeyDown /// </summary> /// <param name="e"></param> protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e) { e.IsInputKey = true; } /// <summary> /// onKeyDown /// </summary> /// <param name="e"></param> protected override void OnKeyDown(KeyEventArgs e) { Input.SetFlag(e.KeyCode); e.Handled = true; } /// <summary> /// onKeyUp /// </summary> /// <param name="e"></param> protected override void OnKeyUp(KeyEventArgs e) { Input.RemoveFlag(e.KeyCode); e.Handled = true; }