Up, Down, Left, and Right Keys Do Not Trigger KeyDown Event

I am creating an application in which all key input should be handled by the windows themselves.

I set tabstop to false for every control that can capture focus except the panel (but I don't know if it has an effect).

I set KeyPreview to true and I am handling the KeyDown event on this form.

My problem is that sometimes the arrow key no longer responds:

  • The keydown event does not fire when I press only the arrow key.

  • The keydown event is fired if I press the arrow key using the control modifier.

Do you have an idea why my arrow key suddenly stops shooting?

+66
c # winforms keydown
Oct 29 '09 at 22:36
source share
10 answers
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; } } 
+56
Apr 09 '11 at 17:40
source share

I had the same problem. I reviewed @Snarfblam's answer; however, if you read the documentation on MSDN, the ProcessCMDKey method is designed to override key events for menu items in the application.

I recently came across this article from Microsoft, which looks pretty promising: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx . According to microsoft, it is best to set e.IsInputKey=true; in the PreviewKeyDown event after detecting the arrow keys. This will trigger the KeyDown .

This worked pretty well for me and was less hacky than overriding ProcessCMDKey.

+58
Oct 19 2018-11-11T00:
source share

See Rodolfo Neuber's answer for a better answer




(My original answer):

Get from the control class, and you can override the ProcessCmdKey method. Microsoft decided to exclude these keys from KeyDown events, since they affect several controls and move focus, but this makes it very difficult for the application to respond to these keys in any other way.

+16
Oct 29 '09 at 22:51
source share

I am using 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; } } 
+16
Jan 24 '13 at 11:32
source share

Unfortunately, this is quite difficult to do with the arrow keys due to limitations in KeyDown events. However, there are several ways around this:

  • As pointed out by @Snarfblam, you can override the ProcessCmdKey method , which retains the ability to parse arrow keys.
  • As the accepted answer from this question, it says that XNA has a built-in Keyboard.GetState () method that allows you to use arrow inputs. However, WinForms does not have this, but it can be done using P / Invoke or using a class that helps with it .

I recommend trying using this class. It is pretty simple:

 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... 

If you use this in conjunction with the KeyDown event, I think you can reliably fulfill your goal.

+2
Oct 29 '09 at 23:01
source share

I had a similar problem when calling a WPF window from WinForms.

 var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); ElementHost.EnableModelessKeyboardInterop(wpfwindow); wpfwindow.Show(); 

However, showing the window as a dialog , he worked

 var wpfwindow = new ScreenBoardWPF.IzbiraProjekti(); ElementHost.EnableModelessKeyboardInterop(wpfwindow); wpfwindow.ShowDialog(); 

Hope this helps.

+2
Oct 10 '16 at 21:17
source share

To capture keystrokes in a Forms control, you should get a new class based on the class of the control you want, and you will override ProcessCmdKey ().

 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { //handle your keys here } 

Example:

 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); } 

Full source ... C # arrow keys

Wayne

0
Jun 19 '14 at 8:00 a.m.
source share

The best way to do, I think, is to process it as MSDN said http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx

But deal with it as you really need it. My way (in the example below) is to catch every 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; } 
0
Dec 20 '14 at 14:11
source share

I had the same problem and I already used the code in the selected answer. this link was the answer for me; perhaps for others.

How to disable WinForm navigation with arrows in C #?

0
Jan 03 '17 at 12:54 on
source share
 protected override bool IsInputKey(Keys keyData) { if (((keyData & Keys.Up) == Keys.Up) || ((keyData & Keys.Down) == Keys.Down) || ((keyData & Keys.Left) == Keys.Left) || ((keyData & Keys.Right) == Keys.Right)) return true; else return base.IsInputKey(keyData); } 
0
Jun 18 '19 at 20:31 on
source share



All Articles