The arrow keys for a container control in .NET are used to switch the focus amongt multiple controls in the container. If a container has several controls, then the arrow keys will move the focus from one control to the next. This is a special behavior for the arrow keys in a container control. In the default case, the arrow keys never reach the controls in the container. There are several ways to get the arrow keys to the controls themselves.
The first way is to allow the arrow keys to maintain the special function that they have. Override the ProcessCmdKey method and add the additional handling of the arrow keys for the control. To allow the keys to have the special function, be sure to call the base class method.
The second technique is to remove the special function altogether. There is another method called IsInputKey.
If the key makes it to the control, then it can be caught in the normal KeyDown handler.
There is a third way, which I will call technique one-and-a-half. If in technique one, the ProcessCmdKey method returns true instead of returning the base class method, then the preprocessing will not be done. This has the same effect as method two. Instead of handling the key in KeyDown, handle the key in ProcessCmdKey.
There is another method for solving this problem: override OnPreviewKeyDown. This method can behave like ProcessCmdKey, but it works for all the keys: extra coding can be done for any key. There is even an event args property for IsInputKey which allows this method to perform like IsInputKey. To remove the command key functionality, set IsInputKey to true.
KeyCode is the code for the key pressed, without any modifiers like Shift or Control.
KeyData is the code for the key OR-ed with any modifier keys, like Shift or Control.
KeyValue is the integer equivalent of KeyData for passing to unmanaged methods.
KeyChar is generated from KeyPress event and has the ASCII code for a key.