2009-12-15 13 views
16

voglio XML-Serialize un tipo complesso (classe), che ha una proprietà di tipo System.Drawing.Bitmap tra gli altri.serializzare una bitmap in C# /. NET XML

/// <summary> 
    /// Gets or sets the large icon, a 32x32 pixel image representing this face. 
    /// </summary> 
    /// <value>The large icon.</value> 
    public Bitmap LargeIcon { get; set; } 

ora ho scoperto che la serializzazione del bitmap con il serializzatore XML di default non funziona, perché non ha un costruttore senza parametri pubblica, che è obbligatorio con il serializzatore predefinito xml.

sono consapevole di quanto segue:

Preferisco non fare riferimento a un altro progetto, né modificare estensivamente la mia classe per consentire solo la serializzazione xml di quei bitmap.

Non c'è modo di mantenerlo così semplice?

Molte grazie, Marcel

risposta

41

vorrei fare qualcosa di simile:

[XmlIgnore] 
public Bitmap LargeIcon { get; set; } 

[Browsable(false),EditorBrowsable(EditorBrowsableState.Never)] 
[XmlElement("LargeIcon")] 
public byte[] LargeIconSerialized 
{ 
    get { // serialize 
     if (LargeIcon == null) return null; 
     using (MemoryStream ms = new MemoryStream()) { 
      LargeIcon.Save(ms, ImageFormat.Bmp); 
      return ms.ToArray(); 
     } 
    } 
    set { // deserialize 
     if (value == null) { 
      LargeIcon = null; 
     } else { 
      using (MemoryStream ms = new MemoryStream(value)) { 
       LargeIcon = new Bitmap(ms); 
      } 
     } 
    } 
} 
+0

Questo è simile alla soluzione fornita dal collegamento nel post originale. Comunque per me, questa sembra essere la soluzione più semplice. – Marcel

+4

Francamente, è l'unica opzione sensata con 'XmlSerializer'. L'implementazione di 'IXmlSerializable' sta chiedendo dolore. –

+0

+1 per questa soluzione. Il codice sorgente funziona bene per me. Grazie molto. – Marcel

2

La classe Bitmap non è stato progettato per essere facilmente XML serializzato. Quindi, no, non c'è un modo semplice per correggere una decisione di progettazione.

+1

Sembra hai ragione, una che è la causa dei miei guai. – Marcel

+0

+1 per indicare questo fuori – Marcel

5

È inoltre possibile implementare ISerializable e utilizzare SerializationInfo per gestire manualmente il contenuto bitmap.

EDIT: João ha ragione: modo corretto di affrontare la serializzazione XML è quello di implementare IXmlSerializable, non ISerializable:

public class MyImage : IXmlSerializable 
{ 
    public string Name { get; set; } 
    public Bitmap Image { get; set; } 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     throw new NotImplementedException(); 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     throw new NotImplementedException(); 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     writer.WriteStartElement("Name"); 
     writer.WriteString(this.Name); 
     writer.WriteEndElement(); 

     using(MemoryStream ms = new MemoryStream()) 
     { 
      this.Image.Save(ms, ImageFormat.Bmp); 
      byte[] bitmapData = ms.ToArray(); 
      writer.WriteStartElement("Image"); 
      writer.WriteBase64(bitmapData, 0, bitmapData.Length); 
      writer.WriteEndElement(); 
     } 
    } 
} 
2

Implementare IXmlSerializable e quindi gestire personalmente tutti i dettagli di serializzazione.

Dal momento che dire che è un tipo grande e hai solo un problema con il bitmap in considerazione fare qualcosa di simile:

public class BitmapContainer : IXmlSerializable 
{ 
    public BitmapContainer() { } 

    public Bitmap Data { get; set; } 

    public XmlSchema GetSchema() 
    { 
     throw new NotImplementedException(); 
    } 

    public void ReadXml(XmlReader reader) 
    { 
     throw new NotImplementedException(); 
    } 

    public void WriteXml(XmlWriter writer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

public class TypeWithBitmap 
{ 
    public BitmapContainer MyImage { get; set; } 

    public string Name { get; set; } 
} 
+0

Non molto praticabile. Ciò implicherebbe una classe derivata e un bel codice. – Marcel