如何从字符串中创建任意System.Drawing.Color?

时间:2012-05-06 19:58:39

标签: c# .net

我有一组独特的字符串,我希望用颜色显示它们。字符串在这里和那里重复,所以我需要着色是一致的,而不是随机的。

一种方法是随机化颜色并将其保存在Dictionary或类似的东西中,这样我就可以再次使用相同的颜色。

另一种方法是提出一种简单的算法/逻辑,以某种方式将字符串转换为System.Drawing.Color

但是,我想将它保留为一组预定义的颜色,这样我最终就不会有那么好的颜色了。我们称之为List<Color> allowedColors

我尝试Convert.ToByte()并认为我会将该字节用于Color的R,G和B组件,但这不起作用,因为转换不起作用。

字符串只是一个简单的字符串String foo = "bar";。颜色和字符串之间的关系无关紧要,只要它是一致的,即,每次运行程序时它应该等于相同的颜色,并且每个字符串的颜色通常应该是不同的(是的,会有重复颜色,因为字符串多于颜色,而不是一对一的映射。

这些字符串来自我无法控制的来源。它们是独一无二的,但各不相同每次启动程序时,如果出现相同的字符串,它应该是相同的颜色。

所以,我想我正在寻找某种字符串到字节的转换,当重叠字节范围重新开始时,最后字节被映射到RGB并发送到Color.FromArgb()

3 个答案:

答案 0 :(得分:1)

如果您有一组已知的唯一字符串和一组预定义颜色,请使用字典:

Dictionary<string, Color> StringColors = new Dictionary<string, Color>()
{
    {"string1", Colors.Red},
    {"string2", Colors.Green},
    {"string3", Colors.Blue},
};

然后它就像:

一样简单
string theString = "string2";
var MyColor = StringColors[theString];

答案 1 :(得分:1)

我认为最简单的方法就是为每个字符串分配AvailableColors列表中的下一个可用颜色,并在第一次创建时将该映射保存到字典中。这可以使用序列化保存到磁盘,并在以后的执行中重用。这是一些(更新的)示例代码:

public Color[] AvailableColors = new Color[] { Colors.Red, Colors.Blue, Colors.Green};         
private int _nextColorIndex = 0;
public Dictionary<string,Color> ColorMappings = new Dictionary<string,Color>();
public Color GetNextColor () 
{
    Color nextColor = AvailableColors[_nextColorIndex];
    _nextColorIndex++;
    if (_nextColorIndex == AvailableColors.Length)
        _nextColorIndex = 0; // Restart colors and reuse.
    return nextColor;
}

public void AssignColor (string myString)
{
    ColorMappings.Add(myString, GetNextColor());
}

当你用完字符串时,你必须添加适当的处理,当然,如果你做多线程的话,可能会在GetNextColor周围进行并发锁定,但这是一个开始。

答案 2 :(得分:1)

您可以使用FramArgb方法制作颜色列表:

var allowedColors = new List<Color>();
allowedColors.Add(Color.FromArgb(255, 0, 0));

或者您可以使用字典管理从字符串到颜色的映射:

var colorMap = new Dictionary<string, Color>();
colorMap.Add("red", Color.FromArgb(255, 0, 0));

在许多情况下,这将被视为一种过度设计的解决方案,但无论如何它都是C#封装的一个例子:

class AppString
{
  private string text;
  private Color color;

  public AppString(string text, Color color)
  {
    this.text = text;
    if(allowedColors.Contains(color))
    {
      this.color = color;
    }
    else
    {
      throw new Exception("invalid color");
    }
  }

  // This lets you use an AppString most places where you used a regular string.
  public static implicit operator string(AppString appString) 
  { 
        return appString.text;
  }

  // This lets you use an AppString most places where you used a Color.
  public static implicit operator Color(AppString appString) 
  { 
        return appString.color;
  }

  // OR if you don't prefer overloading the implicit cast, a standard pattern
  // is to use a Value property.
  public string Value { get { return this.text; } }
  public Color Color { get { return this.color; } }
}