How to determine if KeyCode is printable character
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 charac开发者_JS百科ter?
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.
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.
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.
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
Check this function, you might want to cast char
to byte
(or simply edit the function):
bool IsPrintable(byte item)
{
// Range of chars from space till ~ (tilda)
return item >= 32 && item < 126;
}
精彩评论