Accepting Keyboard Input

Accepting Keyboard Input

Generally speaking, you’ll rarely need to accept keyboard input directly from the user. In most cases, the user provides keyboard input to a control that’s designed to accept input from the keyboard, such as a text box or a rich text control. However, the .NET Framework includes support for handling user input directly. The following subsections describe how you can add support for keyboard input to your programs.

Obtaining the Input Focus

Input through the keyboard isn’t available to all applications and controls simultaneously; instead, it always flows to the control or form that currently has the input focus. Controls generally change their appearance slightly as an indication that they have the input focus—for example, the text box and rich text controls display a vertical bar (¦) at the point where text will be inserted, the button control displays a dashed line around its border, and other controls display similar cues to the user.

To switch focus to a specific control, use the Focus method, which is exposed by the Control class. The Focus method returns true if the input focus was switched to the control or false if the input focus couldn’t be obtained. The following code demonstrates how to use the Focus method:

if(nameTextBox.Focus() == false)
{
    Trace.WriteLine("Couldn't set focus to text box");
} 

The Control class exposes the following three properties related to the input focus:

  • CanFocus  Returns true if the input focus can be switched to the control or false if the input focus can’t be obtained

  • ContainsFocus  Returns true if the control or a child control has the input focus or false if the input focus is owned by another control

  • Focused  Returns true if the control has the input focus; otherwise, returns false

In addition to being exposed by all controls, these properties are available for forms because the Form class is derived from the Control class.

A control can obtain the input focus only if it’s on an active, top-level form. You can test a control to see whether it can get the input focus by using the CanFocus property, as shown here:

if(nameTextBox.CanFocus)
{
    
    

The ContainsFocus property is useful when you need to know whether the control or one of its contained child controls has the input focus, as shown in the following code:

if(this.ContainsFocus)
{
    
    

}

The Focused property is used much like ContainsFocus, except that it doesn’t test child controls.

Instead of testing for the input focus, you can also set up event handlers for the following two events related to the input focus:

  • Enter  Raised when a control or one of its children receives the input focus

  • Leave  Raised when a control or one of its children loses the input focus

You can use the Enter and Leave events to change portions of your user interface to reflect that a specific control has the input focus. For example, you can display help text when a control is able to accept input, as shown here:

private void nameTextBox_Enter(object sender, System.EventArgs e)
{
    helpLabel.Text = "Enter the user's first and last name";
}

private void nameTextBox_Leave(object sender, System.EventArgs e)
{
    helpLabel.Text = "";
}
Using the Keys Enumeration

The Keys enumeration contains constants for all values that can be sent to your application via the keyboard. The enumeration has 183 values and so is too long to list in full here; a complete list is available in the Microsoft Visual C# .NET online help. Table 13-9 lists some examples of keys representative of the values in the Keys enumeration.

As you can see, the values in the Keys enumeration follow some basic patterns. All keys that are associated with characters are available directly, as shown in the following code, which checks to see whether the user has pressed the Q key:

private bool TestForQuitKey(Keys pressedKey)
{
    if(pressedKey == Keys.Q)
        return true;
    else
        return false;
} 

The Keys enumeration makes no distinction between uppercase and lower­case characters. The TestForQuitKey method will return the same value, regardless of the state of the Shift or Caps Lock key. In addition to characters and numbers, function keys and Shift keys are included in the enumeration, as are non-English keyboard keys.

The companion CD includes a program named DisplayKeys that displays all of the values from the enumeration. The source code for DisplayKeys is shown here:

using System;
using System.Windows.Forms;
namespace MSPress.CSharpCoreRef.DisplayKeys
{
    class DisplayKeysApp
    {
        [STAThread]
        static void Main(string[] args)
        {
            string [] keyNames = Enum.GetNames(typeof(Keys));
            foreach(string name in keyNames)
            {
                Console.WriteLine(name);
            }
        }
    }
}

This program retrieves the names of all enumerators in the Keys enumeration and then displays each one.

Handling Events from the Keyboard

Three events are generated when a user presses a key, as follows:

  • KeyDown  Provides raw information about the state of keys and modifiers (Ctrl, Shift, and Alt keys) when a key is pressed.

  • KeyPressed  Provides information about the key character that might result from a pressed key. This event isn’t sent for every pressed key.

  • KeyUp  Provides raw information about the state of keys and modifiers when a key is released.

The KeyUp and KeyDown events receive a parameter of type KeyEvent­Args, a subclass of the EventArgs class. KeyEventArgs includes several properties that simplify the task of processing keyboard input directly, as follows:

  • Alt  Returns true if the Alt key was pressed; otherwise, returns false.

  • Control  Returns true if the Ctrl key was pressed; otherwise, returns false.

  • Handled  Returns a Boolean value that specifies whether the message has been handled.

  • KeyCode  Returns the key code for the primary key that’s associated with the event, taken from the Keys enumeration. The KeyCode property doesn’t combine the key’s value with any modifier keys that were also pressed, such as the Shift, Ctrl, or Alt keys.

  • KeyData  Returns the key code, taken from the Keys enumeration, for the key that was pressed, combined with the values of any Alt, Shift, and Ctrl keys that were pressed.

  • KeyValue  Returns the integer equivalent of the KeyData property.

  • Modifiers  Returns the key codes for any of the Alt, Shift, or Ctrl keys that were pressed.

  • Shift  Returns true if the Shift key was pressed; otherwise, returns false.

The Alt, Control, and Shift properties return true if the user has pressed any of the corresponding keys. These keys receive special treatment because they’re often used to modify the meaning of a key press. For example, in Microsoft Visual Studio .NET, pressing F5 starts an executable in a debugging session, whereas pressing Shift+F5 launches the executable without debugging. One approach to testing for the presence of modifier keys is to use code such as this:

if(e.KeyCode == Keys.Q)
{
    if(e.Shift == true)
    {
        
    

    }
    if(e.Control == true)
    {
        
    

    }
} 

Another approach to testing the state of modifier keys is to use the Modifiers property. This property will contain multiple values if multiple modifier keys are pressed. To determine exactly which keys are pressed, test for the desired modifier keys, as shown here:

if(e.KeyCode == Keys.B)
{
    if(e.Modifiers == (Keys.Control ¦ Keys.Shift)
    {
        
    

    }
} 

If you’re testing for multiple modifier keys, use the Modifiers property as shown here. If you’re testing for a single modifier key, it’s often easier to test the individual properties exposed by the KeyEventArgs class.

The KeyPress event is sent between the KeyDown and KeyUp events. Unlike the KeyDown and KeyUp events, the KeyPress event includes a parameter of type KeyPressEventArgs instead of KeyEventArgs. The KeyPressEventArgs class doesn’t provide information about the key code or modifier keys; instead, it exposes the following properties:

  • Handled  Boolean value that specifies whether the event has been handled

  • KeyChar  Character value that represents the pressed key

The value returned by the KeyChar property will properly reflect the state of the Shift key. The KeyPress event is useful when you’re accepting simple text input and you’re not concerned about modifier keys. The KeyDown and KeyUp events are best suited for handling navigation and function keys.



Part III: Programming Windows Forms