shj shj - 25 days ago 4
C# Question

Serialize Media and Shapes objects

I want to serialize my object as binary or xml.

I used this method to serialize my object. but it gives error : System.Windows.Media.SolidColorBrush not serializable.

My object contains Grid, Ellipse, SolidColorBrush objects.

How can I serialize these objects?

TaW TaW
Answer

You need to create a SerializableBrush class of your own which has constructors taking SolidBrush etc and also a ToBrush method to reconstruct the GDI+ brushes..

The same goes for most other GDI+ objects and structures like Color, Pen etc, some of which, like Color you will even need for the SerializableBrush class..

Adorn it with the [Serializable] attribute! A simple serializable Color class:

[Serializable]
public class SerColor
{
    public byte Red { get; set; }
    public byte Green { get; set; }
    public byte Blue { get; set; }
    public byte Alpha { get; set; }

    public SerColor() { }

    public SerColor(Color c)
    { Red = c.R;  Green = c.G; Blue = c.B; Alpha = c.A; }

    static public Color Color(SerColor c)
    { return System.Drawing.Color.FromArgb(c.Alpha, c.Red, c.Green, c.Blue); }

}

'And a simple serializable SolidBrush class:

[Serializable]
public class SerSolidBrush 
{
    public SerColor sColor { get; set; }

    public SerSolidBrush() { }

    public SerSolidBrush(Color c)
    {
        sColor = new SerColor(c);
    }

    public SerSolidBrush(SolidBrush b)
    {
        sColor = new SerColor(b.Color);
    }


    public SolidBrush SolidBrush()
    {
        Color c = SerColor.Color(sColor);
        return new System.Drawing.SolidBrush(c);
    }

    static public SolidBrush SolidBrush(SerSolidBrush b)
    {
        Color c = SerColor.Color(b.sColor);
        return new System.Drawing.SolidBrush(c);
    }
}

And a small test bed:

SolidBrush brush = new SolidBrush(Color.Red);

SerSolidBrush sBrush = new SerSolidBrush(brush);

XmlSerializer xs = new XmlSerializer(sBrush.GetType());
using (TextWriter tw = new StreamWriter(@"d:\xmlBrush.xml"))
{

    xs.Serialize(tw, sBrush);
    tw.Close();
}
SerSolidBrush sBrush2 = null;
using (TextReader tr = new StreamReader(@"d:\xmlBrush.xml"))
    sBrush2 = (SerSolidBrush) xs.Deserialize(tr);

SolidBrush newBrush = sBrush2.SolidBrush();

This is the resulting xml file ((no idead how to insert xml text in an SO answer properly)):

enter image description here

I hope this shows how to do it; note that SolidBrush is a very simple class with only one property. Pen and most others will be more complicated if you want to support all properties..

Note that simple built-in enums, like LineJoin etc are serializable, so you can simply add the proerties and everything works just fine. To demostrate here is a rather incomplete serilizable Pen class. You will want to add several other properties..:

[Serializable]
public class SerPen 
{
    public SerColor sColor { get; set; }
    public float width { get; set; }
    public LineJoin lineJoin  { get; set; }

    // constructors
    public SerPen() { width = 1f; }

    public SerPen(Color c, float w)
    {
        sColor = new SerColor(c);
        width = w;
    }

    public SerPen(Pen p)
    {
        sColor = new SerColor(p.Color);
        width = p.Width;
        lineJoin = p.LineJoin;
    }

    // re-constructors
    public Pen  Pen ()
    {
        Color c = SerColor.Color(sColor);
        Pen pen = new System.Drawing.Pen (c, width);
        pen.LineJoin = lineJoin;
        return pen;
    }

    static public Pen  Pen (SerPen p)
    {
        Color c = SerColor.Color(p.sColor);
        Pen pen = new System.Drawing.Pen (c, p.width);
        pen.LineJoin = p.lineJoin;
        return pen;
    }
}