如何确定 KeyCode 是否为可打印字符

12

我正在处理一个控件的按键按下事件。如果按下的是实际输入(字母、数字或某种符号),我想将其追加到我的字符串中。如果是控制字符(回车、ESC等),我就不想做任何事情。

有没有一种快速简便的方法来确定按键码是可打印字符还是控制字符?

目前我正在做以下操作:

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

但是我知道在系统处理程序中可能还有一些我不关心的键会执行重要的操作,因此我不想处理它们。

4个回答

17
如果您只想要可打印的字符,那么您可能不需要使用 OnKeyDown。相反,您应该使用 OnKeyPress,它仅针对可打印字符(或者说“几乎”仅针对可打印字符),并为修饰键(主要是 Shift)应用翻译。
我之前提到过“或者说‘几乎’”,因为您还会得到控制字符,这些字符不一定是可打印的。不过,可以使用 char.IsControl 轻松地过滤掉这些字符。
protected override void OnKeyPress(KeyPressEventArgs e){
    if(!char.IsControl(e.KeyChar)){
        // do something with printable character
    }
}

在这样的设计中容易被忽视的是退格键。通常,收到退格字符('\b'(char)8)的最佳行为是从缓冲区中删除最后一个字符。很容易忘记执行此操作。


6
如果您处理KeyPress事件而不是KeyDownKeyPressEventArgs将具有KeyChar属性。这将减少您得到的“额外”键事件数量。然后,您可以使用像char.IsLetterOrDigitchar.IsControl这样的函数来过滤您想要的内容。

5
假设你只有 KeyCode,你可以尝试使用 P/Invoke 调用 MapVirtualKey 函数来解决此问题。但我不确定这是否适用于所有文化。
[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());

输出:

false
false
true
true

-1

检查一下这个函数,你可能想要将char转换为byte(或者简单地编辑该函数):

bool IsPrintable(byte item)
{
    // Range of chars from space till ~ (tilda)
    return item >= 32 && item < 126;
}

1
这仅适用于拉丁可打印字符。它完全忽略所有其他字母表,并错过了许多可打印符号。此外,从char到byte的转换将丢弃信息。C# chars为16位。 - BDL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接