【问题标题】:Convert string to Color in C#在 C# 中将字符串转换为颜色
【发布时间】:2011-03-24 10:01:04
【问题描述】:

我遇到了一个问题,即如何在 C# 中将输入字符串(如“RED”)转换为实际的颜色类型 Color.Red。有什么好办法吗?

我可以考虑为每种颜色类型使用 switch 语句和 case 语句,但我认为这不够聪明。

【问题讨论】:

    标签: c# .net xna


    【解决方案1】:

    以下内容可以从 namehexknown name 生成颜色。

    Color beige = StringToColor("Beige");
    Color purple = StringToColor("#800080");
    Color window = StringToColor("Window");
    
    public static Color StringToColor(string colorStr)
    {
        TypeConverter cc = TypeDescriptor.GetConverter(typeof(Color));
        var result = (Color)cc.ConvertFromString(colorStr);
        return result;
    }
    

    sn-p 取自 Jo Albahari 的 C# in a Nutshell

    【讨论】:

      【解决方案2】:
       Color red = Color.FromName("Red");   
      

      MSDN 没有说任何一种方式,因此它很可能区分大小写。 (更新:显然不是。)

      据我所知,ColorTranslator.FromHtml 也是。

      如果Color.FromName 找不到匹配项,则返回new Color(0,0,0);

      如果ColorTranslator.FromHtml 找不到匹配项,则会引发异常。

      更新:

      由于您使用的是 Microsoft.Xna.Framework.Graphics.Color,这有点棘手:

      using XColor = Microsoft.Xna.Framework.Graphics.Color;
      using CColor = System.Drawing.Color;
      
       CColor clrColor = CColor.FromName("Red"); 
       XColor xColor = new XColor(clrColor.R, clrColor.G, clrColor.B, clrColor.A);
      

      【讨论】:

      • 嘿詹姆斯,谢谢你的评论。因为我在 XNA GameStudio 中开发这个,在我输入你的代码后,程序抱怨:错误 1 ​​'Microsoft.Xna.Framework.Graphics.Color' 确实不包含“FromName”的定义,并且找不到接受“Microsoft.Xna.Framework.Graphics.Color”类型的第一个参数的扩展方法“FromName”(您是否缺少 using 指令或程序集引用?)C: \Users\Guoguo\Desktop\MapWorld2\MapWorld\GameObject.cs 194 27 MapWorld 请问是什么错误?谢谢。
      • +1 用于提及未找到匹配项时的不同行为。
      • Microsoft.Xna.Framework 不是正确的命名空间。使用 System.Drawing
      • 这是在 System.Drawing.Color 中找到的方法,而不是(显然)Microsoft.Xna.Framework.Graphics.Color。
      • @StingyJack:你不能要求 OP 改变他感兴趣的类型!诚然,如果能被告知他感兴趣的类型是什么,那就太好了……
      【解决方案3】:

      这取决于您要查找的内容,如果您需要 System.Windows.Media.Color(如 WPF 中),这很容易:

      System.Windows.Media.Color color = (Color)System.Windows.Media.ColorConverter.ConvertFromString("Red");//or hexadecimal color, e.g. #131A84
      

      【讨论】:

        【解决方案4】:

        最简单的方法:

        string input = null;
        Color color = Color.White;
        
        TextBoxText_Changed(object sender, EventsArgs e)
        {
           input = TextBox.Text;
        }
        
        Button_Click(object sender, EventsArgs e)
        {
           color = Color.FromName(input)
        }
        

        【讨论】:

          【解决方案5】:

          我发现通过 xml-strings 传输颜色:

          Color x = Color.Red; // for example
          String s = x.ToArgb().ToString()
          ... to/from xml ...
          Int32 argb = Convert.ToInt32(s);
          Color red = Color.FromArgb(argb);
          

          【讨论】:

            【解决方案6】:

            这很好地满足了我的需求;)希望有人可以使用它....

                public static Color FromName(String name)
                {
                    var color_props= typeof(Colors).GetProperties();
                    foreach (var c in color_props)
                        if (name.Equals(c.Name, StringComparison.OrdinalIgnoreCase))
                            return (Color)c.GetValue(new Color(), null);
                    return Colors.Transparent;
                }
            

            【讨论】:

              【解决方案7】:

              由于 OP 在评论中提到他使用的是 Microsoft.Xna.Framework.Graphics.Color 而不是 System.Drawing.Color 您可以先创建一个 System.Drawing.Color 然后将其转换为 Microsoft.Xna.Framework.Graphics.Color

              public static Color FromName(string colorName)
              {
                  System.Drawing.Color systemColor = System.Drawing.Color.FromName(colorName);   
                  return new Color(systemColor.R, systemColor.G, systemColor.B, systemColor.A); //Here Color is Microsoft.Xna.Framework.Graphics.Color
              }
              

              【讨论】:

              • 第二行应该是:Color xnaColor = new Color(systemColor.R, systemColor.G, systemColor.B, systemColor.A);但我相信这是完成罗伯特所要求的最简单的方法。
              • ...并且应该添加适当的return 语句:)
              【解决方案8】:

              (如果您能提到您感兴趣的 Color 类型,那就太好了...)

              一种简单的方法是通过反射建立一个字典:

              public static class Colors
              {
                  private static readonly Dictionary<string, Color> dictionary =
                      typeof(Color).GetProperties(BindingFlags.Public | 
                                                  BindingFlags.Static)
                                   .Where(prop => prop.PropertyType == typeof(Color))
                                   .ToDictionary(prop => prop.Name,
                                                 prop => (Color) prop.GetValue(null, null)));
              
                  public static Color FromName(string name)
                  {
                      // Adjust behaviour for lookup failure etc
                      return dictionary[name];
                  }
              }
              

              第一次查找会比较慢(虽然它使用反射来查找所有属性)但之后应该很快。

              如果您希望它不区分大小写,您可以在ToDictionary 调用中传入StringComparer.OrdinalIgnoreCase 之类的额外参数。您可以根据需要轻松添加 TryParse 等方法。

              当然,如果您只需要在一个地方使用它,请不要为单独的课程等烦恼:)

              【讨论】:

              【解决方案9】:

              我以前用过这样的东西:

                      public static T CreateFromString<T>(string stringToCreateFrom) {
              
                      T output = Activator.CreateInstance<T>();
              
                      if (!output.GetType().IsEnum)
                          throw new IllegalTypeException();
              
                      try {
                          output = (T) Enum.Parse(typeof (T), stringToCreateFrom, true);
                      }
                      catch (Exception ex) {
                          string error = "Cannot parse '" + stringToCreateFrom + "' to enum '" + typeof (T).FullName + "'";
                          _logger.Error(error, ex);
                          throw new IllegalArgumentException(error, ex);
                      }
              
                      return output;
                  }
              

              【讨论】:

              • @Jon 我和 ConsoleColor 搞混了。不过,同样的逻辑仍然适用……对吧?他可以代替 Enum.Parse() 对属性名称进行不区分大小写的比较并返回结果。 (显然删除了 IsEnum 检查)。
              • 我认为每次通过反射找到属性会比较痛苦。更好的是,IMO,建立一次字典(根据我的回答)。
              • @Jon 是的,我刷新后看到了。
              【解决方案10】:
              System.Drawing.Color myColor = System.Drawing.ColorTranslator.FromHtml("Red");
              

              (如果您想接受 HTML 样式的十六进制颜色,请使用我的方法。)

              【讨论】:

                猜你喜欢
                • 2013-03-21
                • 2011-02-20
                • 2016-08-11
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-11-02
                相关资源
                最近更新 更多