【问题标题】:ColorTranslator gives incorrect result for SystemColors.HotTrack and Color.TransparentColorTranslator 为 SystemColors.HotTrack 和 Color.Transparent 提供了不正确的结果
【发布时间】:2014-03-27 23:33:10
【问题描述】:

环境

C#、.NET 4.5、DevExpress 13.2.7、Visual Studio 2013

目标

应该选择一种颜色,然后存储并最终检索以供使用。

说明

我的应用程序的用户将选择一个System.Drawing.Color(最好使用DevExpress.XtraEditors.ColorEdit),应用程序将存储它直到需要颜色。目前这是通过将颜色转换为存储的 HTML 字符串来完成的。需要时,string 会转换回System.Drawing.Color。

这适用于大多数颜色,但不适用于SystemColors.HotTrack。当此颜色转换为 HTML 字符串,然后再转换回颜色时,它变为 SystemColors.Highlight。请参阅下面的代码。

var hotTrackColor = SystemColors.HotTrack;
//hotTrackColor   "{Name=HotTrack, ARGB=(255, 0, 102, 204)}"   System.Drawing.Color

var htmlColor = ColorTranslator.ToHtml(hotTrackColor);
//htmlColor   "highlight"   string

var shouldBeHotTrackColor = ColorTranslator.FromHtml(htmlColor);
//shouldBeHotTrackColor   "{Name=Highlight, ARGB=(255, 51, 153, 255)}"   System.Drawing.Color

使用ColorTranslator.ToWin32 和ColorTranslator.FromWin32 方法给出的颜色无法识别为SystemColors.HotTrack,即使颜色本身相同。这会使DevExpress.XtraEditors.ColorEdit 组件无法显示选择了哪种颜色,因此这似乎不是一个合适的解决方案。

使用ColorTranslator.ToOle 和ColorTranslator.FromOle 方法可以得到SystemColors.HotTrack 的正确结果,但不能正确转换Color.Transparent。见下方代码

var transparentColor = Color.Transparent;
//transparentColor   "{Name=Transparent, ARGB=(0, 255, 255, 255)}"   System.Drawing.Color

var oleColor = ColorTranslator.ToOle(transparentColor);
//oleColor   16777215   int

var shouldBeTransparentColor = ColorTranslator.FromOle(oleColor);
//shouldBeTransparentColor   "{Name=White, ARGB=(255, 255, 255, 255)}"   System.Drawing.Color

问题

  1. 为什么ColorTranslator 中的方法不能正确翻译所有颜色?
  2. 在哪里可以了解有关此问题的更多信息?
  3. 我应该怎么做才能以简单的方式实现我的目标?

2014-03-07 更新

好的,似乎没有单一的方法可以为我解决问题。 因此,我使用了 swandog 的解决方案。我在存储颜色时使用颜色名称,在将名称转换回颜色时,我这样做:

//Translate from name, as suggested by swandog.
var translatedColor = Color.FromName(storedColor);

if (!translatedColor.IsKnownColor)
{
    //If the original colour was a custom colour (not a known colour) then
    //the stored colour will contain a HTML-string, like "ff12aadd".

    //Ignore the first two characters (the alpha) and hope
    //that all custom colours uses "ff" as alpha.
    var htmlString = "#" + storedColor.Substring(2);

    translatedColor = ColorTranslator.FromHtml(htmlString);
}

这样,我可以得到正确的颜色,并且仍然可以使用自定义颜色。 到目前为止,它对我来说效果很好。

【问题讨论】:

  • 这是不可避免的,这些转换会丢弃信息。 ToHtml() 让你失去 Name,ToOle() 让你失去 alpha,ToWin32() 让你失去 RGB 顺序。如果您不希望这种情况发生,请不要转换。

标签: c# colors devexpress converter


【解决方案1】:

在http://referencesource-beta.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/ColorTranslator.cs 中查看ToHTML 方法的源代码,您可以看到HotTrack 和Highlight 将产生相同的字符串。

switch (c.ToKnownColor()) {
    case KnownColor.ActiveBorder: colorString = "activeborder"; break;
    case KnownColor.GradientActiveCaption:
    case KnownColor.ActiveCaption: colorString = "activecaption"; break;
    ...
    case KnownColor.HotTrack:
    case KnownColor.Highlight: colorString = "highlight"; break;
    ...
}

DevExpress.XtraEditors.ColorEdit 控件中的自定义颜色选项卡会导致您出现问题,因为它们不会转换回 Web 和系统选项卡中的指定颜色。我要做的是隐藏自定义选项卡

colorEdit1.Properties.ShowCustomColors = false;

然后使用Color.Name 和Color.FromName 来保存和恢复你的颜色:

Color c = colorEdit1.Color;
var colorName = c.Name;
Color restoredColor = Color.FromName(colorName);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-30
    • 2017-02-22
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多