获取 WPF 中 KeyDown 事件的小写字母

7

我想获取键盘按下的键,无论是否开启大写锁定:

private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
   e.Key.ToString();
}

当我在键盘上输入"a"或"A"时,e.Key的结果总是"A"。如何获取输入'a'时得到'a'的结果?
5个回答

8

你不能使用 KeyDown 事件。你需要使用 TextInput 事件。这将打印原始字母及其字幕(大写/小写)。

    private void Window_TextInput(object sender, TextCompositionEventArgs e)
    {
        Console.WriteLine(e.Text);
    }

现在,如果按下Shift等键,则会打印出来。如果您不想要这些修饰符,只需获取字符串的最后一个项目 - 将其视为字符数组即可。

奇怪,TextInput 没有被触发? - olidev
@olidev 检查对象树,确保您将其附加到正确的UIElement上。从Window开始附加事件,然后向下进行。 - Erre Efe
但是textInput事件也会从代码中触发,我只想从键盘输入获取事件处理程序。 - olidev

7

您可以在 KeyDown 事件中使用 Control.IsKeyLocked 方法检查 CAPS lock 是否开启或关闭。另外,您可能需要使用 Modifiers 枚举来检查用户是否使用了 Shift 键输入大写字母,像这样 -

private void Window_KeyDown(object sender, KeyEventArgs e)
{
   string key = e.Key.ToString();
   bool isCapsLockOn = System.Windows.Forms.Control
                        .IsKeyLocked(System.Windows.Forms.Keys.CapsLock);
   bool isShiftKeyPressed = (Keyboard.Modifiers & ModifierKeys.Shift)
                                == ModifierKeys.Shift;
   if (!isCapsLockOn && !isShiftKeyPressed)
   {
      key = key.ToLower();
   }
}

5
重写TextInput/PreviewTextInput (或监听事件)应该能够奏效。
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
    base.OnPreviewTextInput(e);
    Console.WriteLine(e.Text);
}

2

KeyEventArgs类有一个名为“Shift”的字段,表示SHIFT键是否被按下。

否则,由于当CAPS_LOCK被按下时会调用Window_KeyDown方法,您可以保存一个bool值来表示是否按下了CAPS_LOCK键。

    bool isCapsLockPressed;
    private void Window_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
           if(e.KeyCode == Keys.CapsLock) {
               isCapsLockPressed = !isCapsLockPressed;
           }
    }

2
如果应用程序启动时大写锁定键处于打开状态,那会不会导致一切都出错了呢? - Adam Plocher
即使在应用程序没有焦点的情况下按下大写锁定键。 - Phillip

0

处理这个问题的最好方法是使用Window_TextInput事件而不是KeyDown事件。

但是,正如你所说,这个事件在你的应用程序中没有触发,你可以使用类似这样的hack:

bool iscapsLock = false;
bool isShift = false;
private void Window_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.CapsLock)
        iscapsLock = !iscapsLock;

    if (e.Key >= Key.A && e.Key <= Key.Z)
    {
        bool shift = isShift;
        if (iscapsLock)
            shift = !shift;
        int s = e.Key.ToString()[0];
        if (!shift)
        {
            s += 32;
        }
        Debug.Write((char)s);
    }

}

这将根据大写锁定键是否打开正确地打印字符。可以使用此链接检索大写锁定键的初始值:

http://cboard.cprogramming.com/csharp-programming/105103-how-detect-capslock-csharp.html

我希望这对你有用。


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