2013-09-17 5 views
3

Получите немного проблемы. У меня есть программа, которая создает наблюдаемую коллекцию пользователей. Пользователь имеет имя, фамилию и изображение. Я могу добавить пользователя в наблюдаемую коллекцию, но я также хочу сохранить коллекцию и загрузить ее каждый раз, когда я снова открываю программу.Сериализация и сохранение изображения в файле XML

Моя проблема заключается в том, что, хотя довольно легко сохранить имя и фамилию, писатель не может записать изображение в xml-файл. Есть ли способ обойти это?

Вот что я до сих пор:

наблюдаемую коллекции:

ObservableCollection<VendorClass> ProfileList = new ObservableCollection<VendorClass>(); 

проблемного писатель:

XmlSerializer xs = new XmlSerializer(typeof(ObservableCollection<VendorClass>)); 
     using (StreamWriter wr = new StreamWriter("vendors.xml")) //Data/customers.xml 
     { 
      xs.Serialize(wr, ProfileList); 
     } 

Любые идеи? И если существует решение для записи на изображении, существует ли жизнеспособный способ его прочитать?

ответ

5

XmlSerializer не может сериализовать или десериализовать типы изображений WPF, такие как BitmapImage и т. Д. Однако он способен (де) сериализовать байтовые массивы. Таким образом, вы можете добавить свойство byte[] ImageBuffer в свой класс Person, который содержит данные двоичного изображения. Затем вы также установили атрибут XmlIgnore в свойстве Image для подавления его сериализации (de) и установите XmlElement("Image") на свойства ImageBuffer, чтобы (де) сериализовать его как <Image>...</Image>.

public class User 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    [XmlIgnore] 
    public BitmapSource Image { get; set; } 

    [XmlElement("Image")] 
    public byte[] ImageBuffer 
    { 
     get 
     { 
      byte[] imageBuffer = null; 

      if (Image != null) 
      { 
       using (var stream = new MemoryStream()) 
       { 
        var encoder = new PngBitmapEncoder(); // or some other encoder 
        encoder.Frames.Add(BitmapFrame.Create(Image)); 
        encoder.Save(stream); 
        imageBuffer = stream.ToArray(); 
       } 
      } 

      return imageBuffer; 
     } 
     set 
     { 
      if (value == null) 
      { 
       Image = null; 
      } 
      else 
      { 
       using (var stream = new MemoryStream(value)) 
       { 
        var decoder = BitmapDecoder.Create(stream, 
         BitmapCreateOptions.None, BitmapCacheOption.OnLoad); 
        Image = decoder.Frames[0]; 
       } 
      } 
     } 
    } 
} 

Этот подход также был предложен для свойств типа Bitmap в this answer.

+0

Спасибо! Я пытался понять это, и ваш ответ был самым ясным и легким до сих пор. Работала отлично. – user2453973

+0

Добро пожаловать. Альтернативным решением было бы, чтобы пользователь класса реализовал интерфейс «IXmlSerializable», как показано в [этом ответе] (http://stackoverflow.com/a/1907113/1136211). Однако вы должны (де) сериализовать * все * свойства класса в этой реализации. – Clemens

1

Вы бы base64 закодировали изображение, чтобы преобразовать его в строку, а затем записать это в раздел CDATA. См. How do you serialize a string as CDATA using XmlSerializer?

+0

Yikes. Это указывает на меня в правильном направлении, но едва, и нигде так далеко, как по отношению к изображению. – user2453973

Смежные вопросы