1

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

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

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

但是,我想将其保留为一组预定义的颜色,这样我最终不会得到不太好的颜色。让我们称之为List<Color> allowedColors.

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

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

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

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

4

3 回答 3

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];
于 2012-05-06T20:01:54.917 回答
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 周围添加并发锁,但这是一个开始。

于 2012-05-06T20:11:58.607 回答
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; } }
}
于 2012-05-06T20:28:32.983 回答