一尘不染

Color结构的最优雅的XML序列化

c#

一个问题困扰着我,足以在Stack
Overflow上注册。当前,如果我想将Color序列化为XML字符串,命名为color或#rrggbb#aarrggbb,则可以这样做:

[XmlIgnore()]
public Color color;

[XmlElement(ElementName = "Color")]
public String color_XmlSurrogate
{
  get { return MyColorConverter.SetColor(color); }
  set { color = MyColorConverter.GetColor(value); }
}

MyColorConverter就是我喜欢的方式进行序列化。但是,所有这些都感觉像是在与其他领域和所有事物融合在一起。有没有一种方法可以使它以更少的行数运行,也许将TypeDescriptor与与XML相关的C#属性连接起来?


阅读 293

收藏
2020-05-19

共1个答案

一尘不染

这是我用于序列化ColorXML中的结构的一些东西。Color在我看来,这比遮盖主要财产更好。任何建议欢迎。

XmlColor班主要依赖implicit operator语言功能来提供关键数据tranformations。没有这个,该类基本上是无用的。添加了其他功能来完善该类。

XmlColor助手还提供了一个方便的方式来单独颜色分量。我添加了Alpha属性来显示这一点。请注意,Alpha如果将组件一直弯曲到255,则不会对其进行序列化。

反序列化Web颜色值将合并Alpha当前存储在实例中的值。属性的解析顺序无关紧要。如果AlphaXML源中缺少该属性,那么将使用实例组件值来设置Alpha级别。可以说这是有缺陷的。但是,对于XML序列化,XmlColor该类将通过Color.Black将设置Alpha为255进行初始化。

我正在VS2010环境中工作,并针对.Net 4进行构建。我不知道该代码与先前版本的兼容性如何。

这是一个应序列化为XML的示例属性:

    [XmlElement(Type=typeof(XmlColor))]
    public Color MyColor { get; set; }

这是XmlColor帮助程序类:

public class XmlColor
{
    private Color color_ = Color.Black;

    public XmlColor() {}
    public XmlColor(Color c) { color_ = c; }


    public Color ToColor()
    {
        return color_;
    }

    public void FromColor(Color c)
    {
        color_ = c;
    }

    public static implicit operator Color(XmlColor x)
    {
        return x.ToColor();
    }

    public static implicit operator XmlColor(Color c)
    {
        return new XmlColor(c);
    }

    [XmlAttribute]
    public string Web
    {
        get { return ColorTranslator.ToHtml(color_); }
        set {
            try
            {
                if (Alpha == 0xFF) // preserve named color value if possible
                    color_ = ColorTranslator.FromHtml(value);
                else
                    color_ = Color.FromArgb(Alpha, ColorTranslator.FromHtml(value));
            }
            catch(Exception)
            {
                color_ = Color.Black;
            }
        }
    }

    [XmlAttribute]
    public byte Alpha
    {
        get { return color_.A; }
        set { 
            if (value != color_.A) // avoid hammering named color if no alpha change
                color_ = Color.FromArgb(value, color_); 
        }
    }

    public bool ShouldSerializeAlpha() { return Alpha < 0xFF; }
}
2020-05-19