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

如何在c#winforms中显示小写字母的KeyCode和KeyData,c#,winforms,keypress,keydown,C#,Winforms,Keypress,Keydown,我试图在按下的键盘键上显示信息。 此代码正确显示大写字母,但按下小写字母时也会显示大写信息。 我怎样才能解决这个问题? 以下是我想做的: public partial class keyDemo : Form { private void keyDemo_KeyPress(object sender, KeyPressEventArgs e) { charLabel.Text = $"Key pressed: {e.KeyChar}"; } pr

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

我怎样才能解决这个问题? 以下是我想做的:

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 = "";
    }
}

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

如果需要该字符,可能应该使用
KeyPress
而不是
KeyDown
事件

但如果你想这样做:

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

您可以这样做,但它仍然不处理字母以外的键,也不处理Alt Gr(重音字母)。要将击键完全转换为字符,您必须同时转换
键。在大多数键盘上,将
(数字键盘“+”)和Shift“=”添加到“+”,并将“1”通常移动到“!”(取决于您的键盘布局)

您可以通过替换
keytoleter
中的
return null
来扩展它,但这不是获得字符类型的推荐方法

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

使用System.Runtime.InteropServices;//对于GetKeyState
...
私有void keyDemo\u KeyDown(对象发送方,KeyEventArgs e)
{
keyInfoLabel.Text=
$“Alt:{(e.Alt?“是”:“否”)}\n”+
$“Shift:{(e.Shift?“是”:“否”)}\n”+
$“Ctrl:{(e.Control?“是”:“否”)}\n”+
$“KeyCode:{e.KeyCode}\n”+
$“KeyData:{e.KeyData}\n”+
$“KeyValue:{e.KeyValue}\n”+
$“CapsLock:{(CapsLockState?“是”:“否”)}\n”+
$“字母:{KeyToLetter(e.KeyData,CapsLockState)}”;
}
//导入DLL以使用Win32 API调用。
//看https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeystate
//如果使用WPF,则可以使用Keyboard.IsKeyDown:
//  https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.keyboard.iskeydown?view=netframework-4.7.2
[DllImport(“user32.dll”)]
公共静态外部短GetKeyState(键nVirtKey);
/// 
///如果Caps Lock处于启用状态,则为true,否则为false。
/// 
公共图书馆
=>(GetKeyState(Keys.CapsLock)&1)==1;
/// 
///基本关键点(无修改器)。
///当且仅当给定键表示字母时为true。
公共静态布尔键(Keys key)

=>key>=Keys.A&&key如您所见,
Keys.[key]
没有小写字母。大写/小写由Shift和/或CapsLock的状态决定。您还注意到,
KeyPressEventArgs
为字母
返回已处理的值,包括小写表示。KeyDown和KeyUp事件提供虚拟键码。它在世界上任何地方都是相同的,并且与密钥枚举类型匹配。它们产生的字符(如果有的话)取决于活动键盘布局和修改键的状态。例如Shift、Ctrl、Alt。对于具有AltGr键的键盘来说,这会带来额外的复杂性。你知道这个角色将是什么,按键事件会传递它。谢谢你的重播,但是你的解决方案包括键码、键数据吗?因为除了KeyChar之外,它们不会显示在KeyPress事件中。@HashimAl Mansouri
KeyPress
返回键入的字符,而不是键,因此它不提供键代码。
    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://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getkeystate
    // If using WPF, you could use Keyboard.IsKeyDown :
    //  https://docs.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
        }
    }