【问题标题】:ShortcutKey from string来自字符串的快捷键
【发布时间】:2013-09-04 20:38:45
【问题描述】:

我想为用户提供通过配置文件设置ToolStripMenuItem.ShortcutKeys 的选项,所以我发现我需要以某种方式将string 转换为Keys

我已经 already found 如何使用 Enum.Parse 对简单值执行此操作,但它无法识别以下格式:

  • Ctrl+i(末尾有空格)
  • i
  • Ctrl+Alt+Esc

问:是否有任何标准化方式将字符串 (Ctrl+i) 解析为 Keys

我想避免编写我自己的函数,该函数会将文本分成几部分,然后分别处理每个大小写/特殊字符串。

【问题讨论】:

    标签: c# .net keyboard-shortcuts


    【解决方案1】:

    您在“属性”窗口中看到的 ShortcutKeys 属性的字符串是由 TypeConverter 生成的。您也可以在自己的代码中使用该类型转换器。像这样:

        var txt = "Ctrl+I";
        var cvt = new KeysConverter();
        var key = (Keys)cvt.ConvertFrom(txt);
        System.Diagnostics.Debug.Assert(key == (Keys.Control | Keys.I));
    

    请注意ICtrl+Alt+Escape 不是有效的快捷键。 KeysConverter 不会抱怨,分配 ShortCutKeys 属性时会出现异常。用 try/except 包装两者以捕获无效的配置数据。

    【讨论】:

      【解决方案2】:

      是的,您可以使用 , 分隔值 - 但是您的字符串仍需要按摩,因为 CtrlEsc 不是有效的 Keys 值。它们仍然需要是有效值。所以考虑下面的代码:

      var keys = "Ctrl+Alt+Esc";
      keys = keys.Replace("+", ",").Replace("Ctrl", "Control").Replace("Esc", "Escape");
      var k = (Keys)Enum.Parse(typeof(Keys), keys);
      

      此外,这里是 Enum 类中的代码,它将用来处理它:

      string[] array = value.Split(Enum.enumSeperatorCharArray);
      ulong[] array2;
      string[] array3;
      Enum.GetCachedValuesAndNames(runtimeType, out array2, out array3, true, true);
      for (int i = 0; i < array.Length; i++)
      {
          array[i] = array[i].Trim();
          bool flag = false;
          int j = 0;
          while (j < array3.Length)
          {
              if (ignoreCase)
              {
                  if (string.Compare(array3[j], array[i], StringComparison.OrdinalIgnoreCase) == 0)
                  {
                      goto IL_152;
                  }
              }
              else
              {
                  if (array3[j].Equals(array[i]))
                  {
                      goto IL_152;
                  }
              }
              j++;
              continue;
              IL_152:
              ulong num2 = array2[j];
              num |= num2;
              flag = true;
              break;
          }
          if (!flag)
          {
              parseResult.SetFailure(Enum.ParseFailureKind.ArgumentWithParameter, "Arg_EnumValueNotFound", value);
              return false;
          }
      }
      

      enumSeperatorCharArray 的值为:

      private static readonly char[] enumSeperatorCharArray = new char[]
      {
          ','
      };
      

      【讨论】:

      • 我试图避免编写自己的解析器(虽然我最终会得到这样的东西),吐痰+,- 然后修剪空格,使用ToUpper() 单个字符和@987654332 @ 并使用更长的名称进行映射,但根据我的经验,您总是会忘记此类来源中的某些内容。
      • @Vyktor,您不是在编写自己的解析器。但是您必须使字符串进入Enum 类实际上可以Parse 字符串的状态。您希望它如何解析Ctrl?这会奇迹般地变成Control吗?我的意思是你将不得不对它进行一些按摩,但我已经把它放在你可以用, 分开的地方(因为它是内置的),然后只需按摩缩写。
      猜你喜欢
      • 1970-01-01
      • 2016-08-14
      • 1970-01-01
      • 2015-03-14
      • 2011-03-05
      • 1970-01-01
      • 2020-04-28
      • 1970-01-01
      • 2012-08-28
      相关资源
      最近更新 更多