The .NET Framework Windows Form client is a great platform for offering a rich, interactive and responsive user interface. The rich interface of a WinForm client, properly constructed, can offer productivity benefits to the information worker far and above other standard architectures. There are many reasons for increased productivity but one reason comes from how easy it is to leverage the keyboard in a WinForm client.
The Microsoft .NET Framework comes packaged with all the building blocks to implement a keyboard interface in a WinForm application. What this article will illustrate and walk through is how to extend those building blocks with basic .NET controls, inheritance and custom events to create a consistent keyboard interface. The approaches covered do not encompass all possible keyboard interface solutions but aim to offer an idea and direction on how a consistent and efficient keyboard interface can be implemented.
Keep in mind that consistency is crucial when implementing any interface, especially a keyboard interface. Just as easy as it is to increase productivity with the keyboard, it is even easier to decrease productivity by implementing a poorly thought out and inconsistent keyboard interface. For example, if the F1 key pulls up a search box in one form of the application, and deletes records in another form it can be detrimental to the application as a whole. This is why the approaches discussed in this article will focus on keeping the keyboard interface consistent while at the same time make the task of implementing the interface painless and efficient for the .NET developer.
The Basics of Keyboard Interfaces
At the basic level capturing and taking action off of a keyboard command is simple and straight forward. By handling one of a few keyboard events (KeyDown, KeyUp, or KeyPress) on virtually any WinForm .NET Control, keystrokes can be captured and appropriate action taken. The serious problem with this is that the keyboard event would have to be handled individually for every control on the form to make sure that keyboard commands were always captured. Meaning that if a form had 5 buttons, 5 events would have to be handled and coded. This is neither practical nor efficient for the .NET Developer and therefore causes the need to handle the keyboard events at the form level, regardless of what control has focus. The following walks through how to implement an event handler on the form that captures keystrokes.
(All code examples are done using Microsoft Visual Studio 2008 SP1, .NET Framework 3.5 SP1, and running Windows 7 Ultimate 64-bit)
Open Microsoft Visual Studio and create a new Windows Form Application. Place 2 textbox controls and 2 button controls on the form. Open up the properties panel for the default form and rename the form to “MainForm”. There is then a property on the form to set to true that is by default, false. The ‘KeyPreview’ property on the form causes keyboard events fired on controls on the form to be registered with the form first. By handling the events at the form level it eliminates the need to handle them individually at the control level. Once the ‘
KeyPreview‘ property is set to true the next step is to create the event handler on
MainForm to handle the
KeyDown event. Double-clicking the
KeyDown event in the Properties window of
MainForm will generate the event handler in code. Use the code block below to populate the KeyDown method.
private void MainForm_KeyDown(object sender, KeyEventArgs e)
if (e.KeyCode == Keys.Escape)
MessageBox.Show(“Escape Key”, “Keyboard Command”);
else if (e.KeyCode == Keys.F1)
MessageBox.Show(“F1 Key”, “Keyboard Command”);
else if (e.KeyCode == Keys.Enter)
MessageBox.Show(“Enter Key”, “Keyboard Command”);
The above code displays a message box with a message when the Escape, F1 or Enter key is pressed. Run the application and notice that no matter what control has focus on the form the
KeyDown event on the form handles the keyboard command.
KeyEventArgs used in the
KeyDown event can also be used detect when modifiers are used (a combination of keys, such as ‘Ctrl+Alt’) and even control if the keyboard command is passed down to the underlying control.
The problem with using this approach on each individual form is efficiency for the .NET Developer. Using this approach in larger applications with many forms is not only inefficient but prone to introduce consistency issues. An application with dozens of forms will require the .NET Developer to individually setup and configure the keyboard events at a measurable impact to time and cost. This is where implementing an approach to extend
.NET Controls and customizing events comes in. By combining customized .NET Controls and inheritance the required work on the Developer can be reduced while increasing the consistency in the way the keyboard interface is implemented. The rest of this article will explore 2 different approaches to implementing a consistent and efficient interface to a .NET Windows Form client.
NOTE: There is another approach to capturing all keystrokes at the main form level. It involves implementing an
IMessageFilter interface on the form level. While this is more effective in some cases to capture all keystrokes it does have the potential of degrading performance since message filters are being added to the message pump for the application.