如何序列化 Windows.Media.Brush

How to serialize a Windows.Media.Brush

Windows.Media.Brush 不是可序列化的 class 所以我想知道如何序列化它。

我将 [Serializable] 属性放在 class 本身和 [DataContract] 以及每个 属性 上的 [DataMember(Name = "PropertyName")] 所以它看起来像这样:

[Serializable]
[DataContract]
public class ClassName: SerializeableBase<ClassName>
{
    // Color
    [DataMember(Name = "Color")]
    private Brush _color;
    public Brush Color
    {
        get { return _color; }
        set
        {
            _color = value;
        }
    }
}

我的第一个想法是序列化一个十六进制字符串,然后我可以将其转换回画笔。如果我也可以将 Brush 转换为十六进制,这样我就可以在序列化之前更新字符串以及在反序列化字符串后检索颜色,这将起作用。可以转换 Brush 以从中获取十六进制字符串吗?或者是否有更好的序列化方法 class?

要序列化一个不可序列化的 属性,最好使用可序列化的助手 属性 并在两者之间进行转换。您必须编写代码将两个属性同步在一起,以便在序列化时更新它们。这可以通过 setter 来完成。请记住将 NonSerialized 属性添加到 Brush 和任何不可序列化的 属性。

using System;
using System.Runtime.Serialization;
using WindowsMedia = System.Windows.Media;

namespace Something.Something.DarkSide
{
    [NonSerialized]
    private readonly WindowsMedia.BrushConverter _colorConverter = new WindowsMedia.BrushConverter();

    [Serializable]
    [DataContract]
    public class ClassName: SerializeableBase<ClassName>
    {
        [DataMember(Name = "ColorString")]
        private string _colorString;
        public string ColorString
        {
            get { return _colorString; }
            set
            {
                _colorString = value;
                _color = (WindowsMedia.Brush)_colorConverter.ConvertFrom(value);
                OnPropertyChanged();
            }
        }

        // Color
        [NonSerialized]
        private WindowsMedia.Brush _color = WindowsMedia.Brushes.Yellow;
        public WindowsMedia.Brush Color
        {
            get { return _color; }
            set
            {
                _color = value;
                _colorString = _colorConverter.ConvertToString(value);
                OnPropertyChanged();
            }
        }

        // This triggered when deserializing.
        // When deserializing we will have the _color property as null since
        // nothing is setting it. 
        // This ensures we initialize the _color when deserializing from the ColorString property.
        [OnDeserialized]
        private void SetValuesOnDeserialized(StreamingContext context)
        {
            _colorConverter = new WindowsMedia.BrushConverter();
            _color = (WindowsMedia.Brush)_colorConverter.ConvertFrom(ColorString);
        }

        public Annotation(string colorHexValue = null)
        {
            var colorBrush = (WindowsMedia.Brush)_colorConverter.ConvertFrom(colorHexValue);
            Color = colorBrush ?? WindowsMedia.Brushes.Yellow;
        }

        public Annotation(WindowsMedia.Brush colorBrush = null)
        {
            Color = colorBrush ?? WindowsMedia.Brushes.Yellow;
        }
    }
}

*注意:加载序列化文件时,Color 将为 null,不会调用构造函数。然后您必须创建该对象的新实例并使用加载的属性重新构建它,以便它将设置来自 ColorString 的颜色。您还可以在 class 中创建一个辅助方法并在 属性 中调用它来触发此更改,但请记住它 NOT 在序列化加载时发生时间.

var className = ClassName.LoadFromXmlFile(filePath);
// We use the ColorString property because that's what we get after loading
// the serialized file. The Color will be null at this point.
className = new ClassName(className.ColorString);

我在尝试加载它时遇到了一点问题,所以我使用了这个:

public static SerializableType LoadFromXmlFile(string filename)
{
    using (var stream = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 1024))
    {
        using (var reader = XmlDictionaryReader.Create(stream))
        {
            var serializer = new DataContractSerializer(typeof(SerializableType));

            return (SerializableType)serializer.ReadObject(reader);
        }
    }
}