DCSIMG
XmlSerializable and System.Drawing.Color - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

XmlSerializable and System.Drawing.Color

 

יצא לי לכתוב מחלקה שנראית כך:
 

public struct EnviormentColor

{

    public string Name { get; set; }

    public Color ForeColor { get; set; }

    public Color BackColor { get; set; }

}

 
כפי שאפשר לראות המבנה מכיל שם ושני צבעים (צבע רקע וצבע פונט).
 
כעת היה לי מערך של המבנה הזה, ניסיתי להפעיל עליו את מנגנון הסיראליזציה של xml, בצורה הבאה:
 

XmlSerializer serializer = new XmlSerializer(typeof(List<EnviormentColor>));

serializer.Serialize(File.OpenWrite("colors.xml"), list);

 
כעת קרה דבר מעניין, כך נראתה התוצאה:
 
 

<?xml version="1.0"?>

<ArrayOfEnviormentColor>

  <EnviormentColor>

    <Name>Shlomo</Name>

    <ForeColor />

    <BackColor />

  </EnviormentColor>

  <EnviormentColor>

    <Name>Noam</Name>

    <ForeColor />

    <BackColor />

  </EnviormentColor>

  <EnviormentColor>

    <Name>Yossi</Name>

    <ForeColor />

    <BackColor />

  </EnviormentColor>

  <EnviormentColor>

    <Name>david</Name>

    <ForeColor />

    <BackColor />

  </EnviormentColor>

</ArrayOfEnviormentColor>

 
כפי שאפשר לראות רק השמות נכתבו בקובץ אך לא הערכים של הצבעים.
 
לאחר קצת שיטוטים בגוגל, הבנתי שמנגנון הסירלזיציה של xml עושה זאת רק עבור מאפיינים שיש להם get;set; ולמאפיין Name של Color אין set.
 
ישנם כמה דרכים מוזרות לתקן זאת, אני בחרתי בצורה שנראתה לי הכי הגיונית, מימוש של IXmlSerializable, הממשק הזה מאפשר לנו להחליט כיצד יתבצע שיטוח של האובייקטים שלנו.
 
ולכן נשנה את הקוד שלנו קצת.
 

public struct EnviormentColor : IXmlSerializable

{

    public string Name { get; set; }

    public Color ForeColor { get; set; }

    public Color BackColor { get; set; }

 

    #region IXmlSerializable

    public XmlSchema GetSchema()

    {

        throw new NotImplementedException();

    }

 

    public void ReadXml(XmlReader reader)

    {

        Name = reader.ReadElementString();

        BackColor = Color.FromName(reader.ReadElementString());

        ForeColor = Color.FromName(reader.ReadElementString());

 

        reader.ReadEndElement();

    }

 

    public void WriteXml(XmlWriter writer)

    {

        writer.WriteElementString("Name", Name);

        writer.WriteElementString("BackColor", BackColor.Name);

        writer.WriteElementString("ForeColor", ForeColor.Name);

    }

    #endregion

}

 
כעת ההרצה של הקוד המבצע שיטוח של האובייקט ייתן את התוצר הבא:
 

<?xml version="1.0"?>

<ArrayOfEnviormentColor>

  <EnviormentColor>

    <Name>Shlomo</Name>

    <BackColor>Red</BackColor>

    <ForeColor>#aa33ff</ForeColor>

  </EnviormentColor>

  <EnviormentColor>

    <Name>Noam</Name>

    <BackColor>Red</BackColor>

    <ForeColor>#331100</ForeColor>

  </EnviormentColor>

  <EnviormentColor>

    <Name>Yossi</Name>

    <BackColor>Green</BackColor>

    <ForeColor>Blue</ForeColor>

  </EnviormentColor>

</ArrayOfEnviormentColor>

 
 
חשוב לשים לב לשורת ה - reader.ReadEndElement בפונקציית ReadXml, בלי שנקדם בכל פעם את ה - reader לסוף האלמנט הנוכחי, מנגנון הסירליזצייה יחשוב שהגענו לסוף הקובץ ויחזיר רק אלמנט אחד במערך.
פורסם: Feb 19 2012, 12:10 AM by Shlomo | with 1 comment(s)
תגים:, ,
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 5 and 5 and type the answer here:


Enter the numbers above: