SUMMARY
This step-by-step article demonstrates how to trap keystrokes in Windows Forms controls. By using the sample code in this article, you can intercept almost any individual keystroke. You also can intercept key combinations, including CTRL and ALT. This technique does not capture the Print Screen key. Additionally, some keystrokes from keyboards with additional keys, such as keys that control a Web browser or a CD-ROM player, might not be captured.
For most purposes, the standard
KeyUp,
KeyDown, and
KeyPress events are enough to capture and handle keystrokes. However, not all controls raise these events for all keystrokes under all conditions.
For example, consider the
DataGrid control: If no data has been assigned to the grid, the arrow keys (LEFT ARROW, RIGHT ARROW, UP ARROW, and DOWN ARROW) raise only the
KeyUp event. Other keys, such as A or 4, raise all three events. If the
DataGrid is currently displaying data, none of the standard keyboard events are raised for the navigation keys. Keystrokes such as A or 4 raise no events, raise only
KeyUp, or raise all three events, depending on what is currently selected in the control. In these situations, you can follow the steps in this article to capture keystrokes, regardless of the state of the control.
The code samples in this article are written to work with the
DataGrid, because the
DataGrid is the control for which this feature is most frequently requested. You can use the same approach with other .NET controls.
back to the top
Set Up the Key Trap
To trap keystrokes in a Windows Forms control, you must derive a new class that is based on the class of the control that you want, and you override the
ProcessCmdKey method. In this overridden method, you will place the code to process the keystrokes that you want to trap. The following sample code is an example of the basic structure for such a class:
class MyDataGrid : System.Windows.Forms.DataGrid
{
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
}
}
back to the top
Implement the Overridden Method
The system passes two parameters to the
ProcessCmdKey method:
msg and
keyData. The
msg parameter contains the Windows Message, such as WM_KEYDOWN. The
keyData parameter contains the key code of the key that was pressed. If CTRL or ALT was also pressed, the
keyData parameter contains the ModifierKey information.
Using the
msg parameter is not mandatory; you can ignore it. It is good practice, however, to test the message. In this example, you test WM_KEYDOWN to verify that this is a keystroke event. You also test WM_SYSKEYDOWN, so that it is possible to catch keystroke combinations that include control keys (primarily ALT and CTRL).
To trap specific keys, you can evaluate the keyCode by comparing it to the
Keys enumeration. The following code sample demonstrates how to catch the keystrokes UP ARROW, DOWN ARROW, TAB, CTRL+M, and ALT+Z:
const int WM_KEYDOWN = 0x100;
const int WM_SYSKEYDOWN = 0x104;
if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
{
switch(keyData)
{
case Keys.Down:
Console.WriteLine("Down Arrow Captured");
break;
case Keys.Up:
Console.WriteLine("Up Arrow Captured");
break;
case Keys.Tab:
Console.WriteLine("Tab Key Captured");
break;
case Keys.Control | Keys.M:
Console.WriteLine("<CTRL> + m Captured");
break;
case Keys.Alt | Keys.Z:
Console.WriteLine("<ALT> + z Captured");
break;
}
}
back to the top
Build an Example
The following example shows how to trap keystrokes with the
DataGrid control.
- Create a new Windows Control Library project in Visual C#.
- View the properties for the class UserControl1, and then change the name to MyDataGrid.
- View the code for the Control Library, and then change the following line of code
public class MyDataGrid : System.Windows.Forms.UserControl
to the following:
public class MyDataGrid : System.Windows.Forms.DataGrid
Note In Visual Studio 2005, change the following line of code: public partial class MyDataGrid : UserControl
-
Add the following method to the MyDataGrid class:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
const int WM_KEYDOWN = 0x100;
const int WM_SYSKEYDOWN = 0x104;
if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
{
switch(keyData)
{
case Keys.Down:
this.Parent.Text="Down Arrow Captured";
break;
case Keys.Up:
this.Parent.Text="Up Arrow Captured";
break;
case Keys.Tab:
this.Parent.Text="Tab Key Captured";
break;
case Keys.Control | Keys.M:
this.Parent.Text="<CTRL> + M Captured";
break;
case Keys.Alt | Keys.Z:
this.Parent.Text="<ALT> + Z Captured";
break;
}
}
return base.ProcessCmdKey(ref msg,keyData);
}
- Build the project.
- Create a new Windows Application project in Visual C# . By default, Form1 is created.
- On the Tools menu, click Customize Toolbox.
- Click the .NET Framework Components tab.
- Click Browse, find the control/DLL that was just created, and then click OK.
- The control MyDataGrid now appears in the toolbox. Place one on Form1.NOTE: You can use the code in the remaining steps to create sample data for the grid to display.
- Add the following code to the namespace of the form. You can place the code either before or after the Form Class definition.
// This structure is only used in providing sample data for the grid.
public struct gridData
{
private string make;
private int year;
public gridData(string n,int y)
{
make=n;
year=y;
}
public string Make
{
get{return make;}
set{make = value;}
}
public int Year
{
get{return year;}
set{year=value;}
}
}
-
Add the following code to the form class, immediately following the "Windows Form Designer generated code" section:
protected gridData[] dataArray=new gridData[5];
-
Add the following code to the Load event of Form1:
// Create some sample data.
dataArray[0]=new gridData("ford",1999);
dataArray[1]=new gridData("chevrolet",1999);
dataArray[2]=new gridData("plymouth",1988);
dataArray[3]=new gridData("honda",1999);
dataArray[4]=new gridData("fiat",1987);
// Assign the data to the grid.
myDataGrid1.DataSource=dataArray;
- Run the sample, and try the various keystrokes that are being trapped (UP ARROW, DOWN ARROW, TAB, CTRL+M, and ALT+Z). The caption of the form is updated to show which keystroke was pressed.
back to the top