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. The Print Screen key is not affected by
this technique. 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 this is the control for which this feature is most
frequently requested. You can use this same approach with other .NET
controls.
Back to the top
Set Up the Key Trap
To trap keystrokes in a Windows Forms control, you derive a new
class that is based on the class of the control that you want. 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
Inherits DataGrid
Protected Overrides Function ProcessCmdKey( _
ByRef msg As Message, _
ByVal keyData As Keys _
) As Boolean
End Function
End Class
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 involve 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 WM_KEYDOWN As Integer = &H100
Const WM_SYSKEYDOWN As Integer = &H104
If ((msg.Msg = WM_KEYDOWN) Or (msg.Msg = WM_SYSKEYDOWN)) Then
Select Case (keyData)
Case Keys.Down
Console.WriteLine("Down Arrow Captured")
Case Keys.Up
Console.WriteLine("Up Arrow Captured")
Case Keys.Tab
Console.WriteLine("Tab Key Captured")
Case (Keys.Control Or Keys.M)
Console.WriteLine("<CTRL> + m Captured")
Case (Keys.Alt Or Keys.Z)
Console.WriteLine("<ALT> + z Captured")
End Select
End If
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
Basic .NET or in Visual Basic 2005.
- 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
Inherits System.Windows.Forms.UserControl
to the following:
Inherits System.Windows.Forms.DataGrid
- Add the following method to the MyDataGrid class:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, _
ByVal keyData As Keys) As Boolean
Const WM_KEYDOWN As Integer = &H100
Const WM_SYSKEYDOWN As Integer = &H104
If ((msg.Msg = WM_KEYDOWN) Or (msg.Msg = WM_SYSKEYDOWN)) Then
Select Case (keyData)
Case Keys.Down
Me.Parent.Text = "Down Arrow Captured"
Case Keys.Up
Me.Parent.Text = "Up Arrow Captured"
Case Keys.Tab
Me.Parent.Text = "Tab Key Captured"
Case (Keys.Control Or Keys.M)
Me.Parent.Text = "<CTRL> + M Captured"
Case (Keys.Alt Or Keys.Z)
Me.Parent.Text = "<ALT> + Z Captured"
End Select
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
- Build the project.
- Create a new Windows Application project in Visual Basic
.NET or in Visual Basic 2005. By default, Form1 is created.
Note You must change the code in Visual Basic 2005. By default, Visual
Basic creates two files for the project when you create a Windows Forms
project. If the form is named Form1, the two files that represent the form are
named Form1.vb and Form1.Designer.vb. You write the code in the Form1.vb file.
The Windows Forms Designer writes the code in the Form1.Designer.vb file. The
Windows Forms Designer uses the partial keyword to divide the implementation of
Form1 into two separate files. This behavior prevents the designer-generated
code from being interspersed with your code.
For more information
about the new Visual Basic 2005 language enhancements, visit the following
Microsoft Developer Network (MSDN) Web site: For more information about partial classes and the Windows Forms
Designer, visit the following MSDN Web site: - 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.
' Structure is to provide sample data for the example.
Public Structure gridData
Private mmake As String
Private myear As Integer
Public Sub New(ByVal n As String, ByVal y As Integer)
mmake = n
myear = y
End Sub
Public Property Make() As String
Get
Return mmake
End Get
Set(ByVal Value As String)
Make = Value
End Set
End Property
Public Property Year() As Integer
Get
Return myear
End Get
Set(ByVal Value As Integer)
myear = Value
End Set
End Property
End Structure
- Add the following code to the form class immediately
following the "Windows Form Designer generated code" section:
protected dataArray(5) As gridData
- 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