C# 在C语言中将字符串转换为颜色#

C# 在C语言中将字符串转换为颜色#,c#,.net,xna,C#,.net,Xna,我遇到了一个问题,那就是如何将输入字符串(如“RED”)转换为C#中的实际颜色类型Color.RED。有什么好办法吗 我可以考虑对每种颜色类型使用switch语句和cases语句,但我认为这不够聪明 System.Drawing.Color myColor = System.Drawing.ColorTranslator.FromHtml("Red"); (如果要接受HTML样式的十六进制颜色,请使用我的方法。) MSDN没有这样或那样说,所以它很有可能是区分大小写的。(更新:显然不是。) 据

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

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

System.Drawing.Color myColor = System.Drawing.ColorTranslator.FromHtml("Red");
(如果要接受HTML样式的十六进制颜色,请使用我的方法。)

MSDN没有这样或那样说,所以它很有可能是区分大小写的。(更新:显然不是。)

据我所知,
colorplator.FromHtml
也是

如果
Color.FromName
找不到匹配项,则返回
新颜色(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);

我以前用过类似的方法:

        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;
    }
公共静态T CreateFromString(string stringToCreateFrom){ T output=Activator.CreateInstance(); 如果(!output.GetType().IsEnum) 抛出新的非法类型异常(); 试一试{ output=(T)Enum.Parse(typeof(T),stringToCreateFrom,true); } 捕获(例外情况除外){ string error=“无法将“+stringToCreateFrom+”解析为enum”+typeof(T).FullName+”; _记录器错误(错误,ex); 抛出新的IllegalArgumentException(错误,ex); } 返回输出; }
(如果您先提到您感兴趣的
颜色,
类型,那就太好了…)

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

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];
    }
}
公共静态类颜色
{
专用静态只读字典=
typeof(Color).GetProperties(BindingFlags.Public)
BindingFlags.Static)
.其中(prop=>prop.PropertyType==typeof(颜色))
.ToDictionary(prop=>prop.Name,
prop=>(颜色)prop.GetValue(null,null));
公共静态颜色FromName(字符串名称)
{
//调整查找失败等的行为
返回字典[名称];
}
}
对于第一次查找,这将相对缓慢(虽然它使用反射来查找所有属性),但之后应该非常快

如果希望它不区分大小写,可以在
ToDictionary
调用中作为额外参数传入类似
StringComparer.OrdinalIgnoreCase
的内容。如果愿意,您可以轻松添加
TryParse
etc方法


当然,如果你只在一个地方需要这个,不要为单独的类等而烦恼:)

因为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
}

这很好地满足了我的需要;)希望有人能使用它

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

对于通过xml字符串传输颜色,我发现:

Color x = Color.Red; // for example
String s = x.ToArgb().ToString()
... to/from xml ...
Int32 argb = Convert.ToInt32(s);
Color red = Color.FromArgb(argb);
最简单的方法是:

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)
}

这取决于您要查找的内容,如果您需要System.Windows.Media.Color(如WPF中的),它非常简单:

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

以下内容可以从名称十六进制已知名称生成颜色

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

该片段取自Jo Albahari的。

嘿,James,谢谢你的评论。因为我是在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更改他感兴趣的类型!诚然,如果有人告诉我他感兴趣的是哪种类型,那就太好了…@Jon我和ConsoleColor混在一起了。但同样的逻辑仍然适用。。。正确的?他可以对属性名执行不区分大小写的比较,而不是Enum.Parse(),并返回结果。(显然是删除了IsEnum检查)。我认为每次通过反射查找属性都会比较痛苦。我觉得最好(按照我的回答)编一本字典。@Jon是的,我刷新后看到了。第二行应该是:Color xnaColor=new Color(systemColor.R,systemColor.G,systemColor.B,systemColor.a);但我相信这是实现Robert要求的最简单的方法……而且还应该添加一个适当的
返回
语句:)看起来这是回答这个问题相反的最好方法:
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;
}