代码之家  ›  专栏  ›  技术社区  ›  Björn Larsson

ColorTranslator为SystemColors.HotTrack和Color.Transparent提供了错误的结果

  •  1
  • Björn Larsson  · 技术社区  · 12 年前

    环境

    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 给出的颜色不被识别为 系统颜色.HotTrack 即使颜色本身是相同的。这将渲染 DevExpress.XtraEditors颜色编辑 组件无法显示选择的颜色,因此这似乎不是一个合适的解决方案。

    使用这些方法 ColorTranslator.ToOle ColorTranslator.FromOle 给出正确的结果 系统颜色.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);
    }
    

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

    1 回复  |  直到 11 年前
        1
  •  2
  •   swandog    12 年前

    在源中查找 ToHTML 方法位于 http://referencesource-beta.microsoft.com/#System.Drawing/commonui/System/Drawing/Advanced/ColorTranslator.cs ,你可以看到两者 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);