C# 如何将字符转换为等效的 System.Windows.Input.Key 枚举值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/544141/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:34:30  来源:igfitidea点击:

How to convert a character in to equivalent System.Windows.Input.Key Enum value?

c#.netenumsinputkey

提问by Vin

I want to write a function like so,

我想写一个这样的函数,

        public System.Windows.Input.Key ResolveKey(char charToResolve)
        {
            // Code goes here, that resolves the charToResolve
            // in to the Key enumerated value
            // (For example with '.' as the character for Key.OemPeriod)

        }

I know I can write a huge Switch-case to match the character, but is there any other way? The thing with this is the Key enum's string may not match with the character so Enum.IsDefined will not work

我知道我可以写一个巨大的 Switch-case 来匹配角色,但还有其他方法吗?与此相关的是 Key 枚举的字符串可能与字符不匹配,因此 Enum.IsDefined 将不起作用

Any ideas?

有任何想法吗?

Update: This is in Windows environment

更新:这是在 Windows 环境中

采纳答案by xcud

[DllImport("user32.dll")]
static extern short VkKeyScan(char ch);

static public Key ResolveKey(char charToResolve)
{
    return KeyInterop.KeyFromVirtualKey(VkKeyScan(charToResolve));
}

回答by Joacim Andersson

Try using the ConvertFrom method of the System.Windows.Input.KeyConverter class.

尝试使用 System.Windows.Input.KeyConverter 类的 ConvertFrom 方法。

回答by Nasenbaer

Hi Just convert that way

嗨,就这样转换

Dim KeyConverter As New Forms.KeysConverter    
Dim S As String = KeyConverter.ConvertToString(e.Key)
Dim O As System.Windows.Forms.Keys = KeyConverter.ConvertFrom(S)
Dim ChValue As Integer = CType(O, Integer) 

In my case I press "ENTER" on my keyboard, Ois going into ENTER {13}and ChValue is going into Character Code 13For TABKey I will receive Character Code 9that way for example.

在我的情况下,我按键盘上的“ENTER”键,O然后进入ENTER {13}ChValue 进入字符代码,13例如,TAB我会以9这种方式接收字符代码。

回答by Mojtaba Rezaeian

Recently I found a great answer for similar question from Jon Hannawhich can handle control key states as well:

最近我从 Jon Hanna那里找到了一个很好的类似问题的答案,它也可以处理控制关键状态:

This one might be more easily explained with an example program than anything else:

使用示例程序可能比其他任何东西都更容易解释这一点:

namespace KeyFinder
{
  class Program
  {
    [DllImport("user32.dll", CharSet = CharSet.Unicode)]
    static extern short VkKeyScanEx(char ch, IntPtr dwhkl);
    [DllImport("user32.dll")]
    static extern bool UnloadKeyboardLayout(IntPtr hkl);
    [DllImport("user32.dll")]
    static extern IntPtr LoadKeyboardLayout(string pwszKLID, uint Flags);
    public class KeyboardPointer : IDisposable
    {
      private readonly IntPtr pointer;
      public KeyboardPointer(int klid)
      {
        pointer = LoadKeyboardLayout(klid.ToString("X8"), 1);
      }
      public KeyboardPointer(CultureInfo culture)
        :this(culture.KeyboardLayoutId){}
      public void Dispose()
      {
        UnloadKeyboardLayout(pointer);
        GC.SuppressFinalize(this);
      }
      ~KeyboardPointer()
      {
        UnloadKeyboardLayout(pointer);
      }
      // Converting to System.Windows.Forms.Key here, but
      // some other enumerations for similar tasks have the same
      // one-to-one mapping to the underlying Windows API values
      public bool GetKey(char character, out Keys key)
      {
        short keyNumber = VkKeyScanEx(character, pointer);
        if(keyNumber == -1)
        {
          key = System.Windows.Forms.Keys.None;
          return false;
        }
        key = (System.Windows.Forms.Keys)(((keyNumber & 0xFF00) << 8) | (keyNumber & 0xFF));
        return true;
      }
    }
    private static string DescribeKey(Keys key)
    {
      StringBuilder desc = new StringBuilder();
      if((key & Keys.Shift) != Keys.None)
        desc.Append("Shift: ");
      if((key & Keys.Control) != Keys.None)
        desc.Append("Control: ");
      if((key & Keys.Alt) != Keys.None)
        desc.Append("Alt: ");
      return desc.Append(key & Keys.KeyCode).ToString();
    }
    public static void Main(string[] args)
    {
      string testChars = "Aé?";
      Keys key;
      foreach(var culture in (new string[]{"he-IL", "en-US", "en-IE"}).Select(code => CultureInfo.GetCultureInfo(code)))
      {
        Console.WriteLine(culture.Name);
        using(var keyboard = new KeyboardPointer(culture))
          foreach(char test in testChars)
          {
            Console.Write(test);
            Console.Write('\t');
            if(keyboard.GetKey(test, out key))
              Console.WriteLine(DescribeKey(key));
            else
              Console.WriteLine("No Key");
          }
      }
      Console.Read();//Stop window closing
    }
  }
}

Output:

输出:

he-IL
A  Shift: A
é  No Key
?  A
en-US
A  Shift: A
é  No Key
?  No Key
en-IE
A  Shift: A
é  Control: Alt: E
?  No Key

(Though your own console might mess up ? and/or é depending on settings and fonts).

(尽管您自己的控制台可能会搞砸 ? 和/或 é 取决于设置和字体)。

Read full descriptions from referenced answer

参考答案中阅读完整说明