I'm building a small Forms application, i've just started it. But i have this problem: if i put a Control to the form, the KeyDown event is not firing. I'm aware of the KeyPreview property, and set it to true. But that didn't helped... :( I also tried to set the focus to the main form, no success either.
Any thoughts?
Edit:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
KeyDown += new KeyEventHandler(Form1_KeyDown);
this.KeyPreview = true;
}
void Form1_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Left: MessageBox.Show("Left");
break;
case Keys.Right: MessageBox.Show("Right");
break;
}
}
}
The reason of the behaviour you observe is that special keys like TAB, UP/DOWN/LEFT/RIGHT ARROW, PAGE UP/DOWN, HOME, END, etc. are often considered "Input Keys" by common controls.
For example, ARROW keys are considered "Input Keys" by the TabControl as these keys allows you to change the selected TabPage. A similar behaviour is present with a multiline TextBox where the ARROWS keys allows you to move the text cursor.
I assume that the Rumba Mainframe control you have does the same thing for the same reasons. You can try overriding it and changing the implementation of the IsInputKey method or handling the PreviewKeyDown event and setting the IsInputKey property to true.
Please see the documentation of the Control.IsInputKey Method and Control.PreviewKeyDown Event for further details
If you were on WPF, you could easily catch the required events, because WPF uses routed event system to dispatch events. In winforms, I recomment one of these two ways:
1. Using
Application.AddMessageFilter Method
:Define a Message Filter class:
So you have a class that every message in Windows Forms passes through it. You can do whatever you want with the event. If
PreFilterMessage
method returns true, it means that the event should not be dispatched to it's respcetive control.(Note that the values in the
Keys
enumeration is almost idential to virtual key codes)Before this works, you have to add it to the application's message filters:
The filter is only active in the lifetime of the
Form1
.Notice: This will catch events in any form! If you want it to work for only one form, pass the form to the filter class, and compare its
Handle
property withm.HWnd
inPreFilterMessage
2. Using Windows Hooks:
This is a more advanced and complicated (and low level) approach. And it requires more code. I've wrote a
HookManager
class that makes the process very simple. I'm gonna publish the class to github and write an article about it.The arrow keys are one kind of special key that are automatically handled by Controls. So if you want to make them raise the KeyDown event you could:
1) Override the isInputKey method in every control of your form
OR
2) Handle the PreviewKeyDown event and set the IsInputKey property to true
More info can be found here.
I know WonderCsabo solved his problem already but someone else put a bounty on it because is having the same problem and no answer was selected. WonderCsabo please post your solution as answer as well.
I already commented my solution, but I also post it as an answer, so it can be easily found.