XmlSerializable and System.Drawing.Color

19 בפברואר 2012

תגיות: , ,
תגובה אחת


 


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

 



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 לסוף האלמנט הנוכחי, מנגנון הסירליזצייה יחשוב שהגענו לסוף הקובץ ויחזיר רק אלמנט אחד במערך.

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

תגובה אחת

  1. jossef24 בפברואר 2012 ב 20:12

    מעניין, תודה על השיתוף.

    להגיב