2015-04-06 4 views
3

Windows.Media.Brush не является сериализуемым классом, поэтому мне интересно, как его сериализовать.Как сериализовать Windows.Media.Brush

Я ставлю перед [Serializable] атрибут самого класса и [DataContract], а вместе с [DataMember (Name = «ИмениСвойство»)] на каждое свойстве, так это выглядит примерно так:

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

Моя первая мысль состоит в том, что я сериализую шестнадцатеричную строку, которую я могу затем преобразовать, чтобы быть кистью. Это сработает, если я смогу преобразовать кисть в шестнадцатеричную, чтобы обновить строку до ее сериализации, а также получить цвет после десериализации строки. Можно ли преобразовать кисть, чтобы получить из нее шестнадцатеричную строку? Или есть лучший способ сериализации этого класса?

+0

Посмотрите этот http://stackoverflow.com/questions/4488476/how-can-i- serialize-xaml-brush – eYe

+0

Видел это решение, но не упоминает, как это будет работать с другими свойствами? Я все еще смотрю в нее. Спасибо. – AzzamAziz

+1

Используйте класс BrushConverter, чтобы вы могли сериализовать его как строку. –

ответ

2

Чтобы сериализовать свойство unserializable, лучше использовать вспомогательное свойство, которое сериализуется и выполняет преобразование между ними. Вы должны написать код, чтобы синхронизировать оба свойства вместе, чтобы они обновлялись ко времени сериализации. Это можно сделать с помощью сеттера. Не забудьте добавить атрибут 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; 
     } 
    } 
} 

* Примечание: При загрузке файла сериализованного цвет будет нулевым, и конструктор не будет вызван. Затем вы должны создать новый экземпляр объекта и перестроить его с помощью загруженных свойств, чтобы он установил цвет из ColorString. Вы также можете создать вспомогательный метод в классе и вызвать его для свойства, чтобы вызвать это изменение, но помните, что он 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); 
     } 
    } 
}