c# - 如何序列化 Windows.Media.Brush

标签 c# .net wpf serialization brush

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

我将 [Serializable] 属性放在类本身上,将 [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 以从中获取十六进制字符串吗?或者是否有更好的序列化此类的方法?

最佳答案

要序列化不可序列化的属性,最好使用可序列化的辅助属性并在两者之间进行转换。您必须编写代码将两个属性同步在一起,以便在序列化时更新它们。这可以通过 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 的颜色。您还可以在类中创建辅助方法并在属性上调用它以触发此更改,但请记住它不会在序列化加载时发生。

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);
        }
    }
}

关于c# - 如何序列化 Windows.Media.Brush,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29472270/

相关文章:

c# - Visual Studio 解决方案引用

c# - 如何在单个事务中将文件写入磁盘并插入数据库记录?

wpf - Visual Studio 2010 解决方案的 MSBuild 命令行执行无法引用 VS2010 SDK 来构建扩展

c# - 如何在 WPF 中使模型类可观察

c# - 图片不出现在电子邮件中

c# - 无法在 TextBox 样式上设置 CornerRadius

c# - 在 "using(object that implements iDisposable)"语句中返回方法是否正确?

c# - 如何将服务器服务连接到 Dynamics Online

java - Java和.Net在JIT上有什么区别

C# 从 App.xaml.cs 访问 WPF 主窗口中的静态属性时导致这种奇怪行为的原因