Up, Down, Left and Right arrow keys do not trigger KeyDown event
I am building an application where all the key input must be handled by the windows itself.
I set tabstop to false for each control witch could grab the focus except a panel (but I don't know if it has effect).
I set KeyPreview to true and I am handling the KeyDown event on this form.
My problem is that sometimes the arrow key aren't responsive anymore:
The keydown event is not fired when I pressed only an arrow key.
The keydown event is fired if I press an arrow key with the control modifier.
Have you an idea why my arrow key suddenly stop firing event?
Solution 1:
I was having the exact same problem. I considered the answer @Snarfblam provided; however, if you read the documentation on MSDN, the ProcessCMDKey method is meant to override key events for menu items in an application.
I recently stumbled across this article from microsoft, which looks quite promising: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.previewkeydown.aspx. According to microsoft, the best thing to do is set e.IsInputKey=true;
in the PreviewKeyDown
event after detecting the arrow keys. Doing so will fire the KeyDown
event.
This worked quite well for me and was less hack-ish than overriding the ProcessCMDKey.
Solution 2:
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;
}
}
Solution 3:
I'm 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;
}
}
Solution 4:
See Rodolfo Neuber's reply for the best answer
(My original answer):
Derive from a control class and you can override the ProcessCmdKey method. Microsoft chose to omit these keys from KeyDown events because they affect multiple controls and move the focus, but this makes it very difficult to make an app react to these keys in any other way.