如何在c# winforms中显示小写字母的KeyCode和KeyData

问题描述 投票:0回答:2

我正在尝试显示按下的键盘按键上的信息。
此代码正确显示大写字母,但按下小写字母时也会显示大写信息。

如何解决这个问题? 这就是我正在尝试做的事情:

public partial class keyDemo : Form
{
    private void keyDemo_KeyPress(object sender, KeyPressEventArgs e)
    {
        charLabel.Text = $"Key pressed: {e.KeyChar}";
    }

    private void keyDemo_KeyDown(object sender, KeyEventArgs e)
    {
        keyInfoLabel.Text =
            $"Alt: {(e.Alt ? "Yes" : "No")}\n" +
            $"Shift: {(e.Shift ? "Yes" : "No")}\n" +
            $"Ctrl: {(e.Control ? "Yes" : "No")}\n" +
            $"KeyCode: {e.KeyCode}\n" +
            $"KeyData: {e.KeyData}\n" +
            $"KeyValue: {e.KeyValue}";
    }

    private void keyDemo_KeyUp(object sender, KeyEventArgs e)
    {
        charLabel.Text = "";
        keyInfoLabel.Text = "";
    }
}

it shows uppercase info but the pressed key is lowercase

c# winforms keypress keydown
2个回答
2
投票

这样做的原因是

KeyEventArgs
返回键的详细信息,而不是字符。 (大写和小写字母使用相同的键。) 有些键不产生字符(例如 Shift、F 键),有些键产生不可打印的字符(例如 Tab、Escape),并且某个击键产生的字符取决于您的键盘布局。

如果您想要该角色,您可能应该使用

KeyPress
而不是
KeyDown
事件。

但是如果你想这样做:

正如 @PrinceOfRavens 所说,您必须检查 Caps Lock 键的状态。

你可以这样做,但这仍然不能处理字母以外的键,并且不能处理 Alt Gr (对于重音字母)。要将击键完全转换为字符,您必须将大多数键盘上的

Keys.Add
(数字键盘“+”)和 Shift“=”转换为“+”,并将 Shift“1”通常转换为“!” (取决于您的键盘布局)。

您可以通过替换

return null
中的
KeyToLetter
来扩展它,但这不是推荐的输入字符的方法

(我已在输出中添加了两项。)

    using System.Runtime.InteropServices;   // for GetKeyState

    ...


    private void keyDemo_KeyDown(object sender, KeyEventArgs e)
    {
        keyInfoLabel.Text =
            $"Alt: {(e.Alt ? "Yes" : "No")}\n" +
            $"Shift: {(e.Shift ? "Yes" : "No")}\n" +
            $"Ctrl: {(e.Control ? "Yes" : "No")}\n" +
            $"KeyCode: {e.KeyCode}\n" +
            $"KeyData: {e.KeyData}\n" +
            $"KeyValue: {e.KeyValue}\n" +
            $"CapsLock: {(CapsLockState ? "Yes" : "No")}\n" +
            $"Letter: {KeyToLetter(e.KeyData, CapsLockState)}";
    }

    // Import the DLL to use a Win32 API call.
    // See https://learn.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeystate
    // If using WPF, you could use Keyboard.IsKeyDown :
    //  https://learn.microsoft.com/en-us/dotnet/api/system.windows.input.keyboard.iskeydown?view=netframework-4.7.2
    [DllImport("user32.dll")]
    public static extern short GetKeyState(Keys nVirtKey);

    /// <summary>
    /// true if Caps Lock is on, otherwise false.
    /// </summary>
    public bool CapsLockState 
        => (GetKeyState(Keys.CapsLock) & 1) == 1;

    /// <summary/>
    /// <param name="key">A base key (no modifiers).</param>
    /// <returns>true if and only if the given key represents a letter.</returns>
    public static bool IsLetterKey(Keys key)
        => key >= Keys.A && key <= Keys.Z;

    /// <summary>
    /// Given a keystroke that produces a letter, this returns the letter.
    /// </summary>
    /// <param name="key"></param>
    /// <param name="capsLockState"></param>
    /// <returns>the letter, or null if the given keystroke does not produce a letter.</returns>
    public static char? KeyToLetter(Keys key, bool capsLockState)
    {
        Keys baseKey = key & ~Keys.Modifiers;  // remove modifier keys
        if (IsLetterKey(baseKey) && !key.HasFlag(Keys.Control))    // if a letter
        {
            bool shiftPressed = key.HasFlag(Keys.Shift);   // check whether Shift was pressed
            bool capital = capsLockState ^ shiftPressed;   // if it should be capital
            if (capital)
                return (char)baseKey;
            else
                return Char.ToLower((char)baseKey);
        }
        else
        {
            return null;  // not a letter
        }
    }

0
投票

代码不必太复杂,添加即可

 if (e.KeyCode == Keys.[Key] && e.KeyCode != Keys.Capital)
 {
    //do whatever here
 }
© www.soinside.com 2019 - 2024. All rights reserved.