views:

63

answers:

3

I am handling the key down event on one of my controls. If the key pressed is an actual input (alphabetic, numeric, or symbol of some kind) I want to append it to a string I have. If it is a control character (enter, escape, etc..) I don't want to do anything.

Is there a quick and easy way to determine if the key code is a printable character or a control character?

Currently I am doing

if (e.KeyCode == Keys.Enter)
      {
        e.Handled = false;
        return;
      }

But I know there are probably a few more keys I don't care about that do something important in the system handler, so I don't want to handle them.

+4  A: 

If you handle the KeyPress event instead of KeyDown, the KeyPressEventArgs will have a KeyChar property. That will reduce the number of "extra" key events you get. You can then use something like char.IsLetterOrDigit or char.IsControl to filter what you want.

Bob
+2  A: 

If you only want printable characters, then you probably don't want OnKeyDown. You should be using OnKeyPress instead, which is called only for printable characters (more or less), and applies translations for modifier keys (Shift, primarily).

I said "more or less" above, because you will also get control characters, which aren't necessarily printable. Those can easily be filtered out with char.IsControl, though.

protected override void OnKeyPress(KeyPressEventArgs e){
    if(!char.IsControl(e.KeyChar)){
        // do something with printable character
    }
}

Something that's easy to overlook in a design like this is the backspace key. Typically, the best behavior upon receiving a backspace character ('\b', or (char)8) is to remove the last character from your buffer. It's easy to forget to do this.

P Daddy
A: 

Assuming you only have the KeyCode, you can trying P/Invoking into the MapVirtualKey function. I'm not sure if this will work for all cultures.

[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int MapVirtualKey(int uCode, int uMapType);

public static bool RepresentsPrintableChar(this Keys key)
{
   return !char.IsControl((char)MapVirtualKey((int)key, 2));
}

Console.WriteLine(Keys.Shift.RepresentsPrintableChar());
Console.WriteLine(Keys.Enter.RepresentsPrintableChar());
Console.WriteLine(Keys.Divide.RepresentsPrintableChar());
Console.WriteLine(Keys.A.RepresentsPrintableChar());

Output:

false
false
true
true
Ani