Use XML serialization to save and restore pictures drawn by the user in C#

The example Make an enhanced scribble application that lets the user draw in different colors, line thicknesses, and line styles in C# explains how to let the user draw curves. This example adds to that one to let you save and load pictures drawn by the user.

It turns out, this is remarkably easy. The following code shows how the program saves the Polyline objects stored in the Polylines list.
// Save the drawing.
private void mnuFileSaveAs_Click(object sender, EventArgs e)
{
if (sfdFile.ShowDialog() == DialogResult.OK)
{
XmlSerializer xml_serializer = new XmlSerializer(Polylines.GetType());
using (StreamWriter stream_writer = new StreamWriter(sfdFile.FileName))
{
xml_serializer.Serialize(stream_writer, Polylines);
stream_writer.Close();
}
}
}

The code displays a SaveFileDialog. If the user selects a file and clicks Save, the program create an XmlSerializer object. It passes the constructor the type of the thing that it will serialize. In this case, that's the data type of the Polylines variable, which is List<Polyline>.

The program then creates a StreamWriter associated with the file. It calls the serializer's Serialize method, passing it the StreamWriter and the object to serialize.

The following code shows how the program deserializes a serialized file.

// Open a saved drawing.
private void mnuFileOpen_Click(object sender, EventArgs e)
{
if (ofdFile.ShowDialog() == DialogResult.OK)
{
try
{
XmlSerializer xml_serializer = new XmlSerializer(Polylines.GetType());
using (FileStream file_stream = new FileStream(ofdFile.FileName, FileMode.Open))
{
List new_polylines =
(List)xml_serializer.Deserialize(file_stream);
Polylines = new_polylines;
picCanvas.Refresh();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}

This code displays a SaveFileDialog. If the user selects a file and clicks Save, the program again creates an XmlSerializer for the data type of the Polylines object.

Next the program creates a FileStream associated with the file, opening it as it creates the FileStream.

The code then calls the serializer's Deserialize method. The result is an object so the program casts it to the List<Polyline> type. It finally saves the result in the variable Polylines and refreshes the drawing PictureBox.

If those were the only changes you made, you would be able to save and restore Polylines but they would be missing their Color properties. It turns out, that all of the other properties of the Polyline class are integers, DashStyles, and even List<Point> all serialize automatically but the Color class does not. That means when you serialize a list of Polylines, their colors are not saved. When you reload a file, the program draws the Polylines but you don't see them because their colors are not reloaded.

The workaround is to create a property that represents Color but that can be serialized. This example uses an Argb property that gets and sets the color's alpha, red, green, and blue color components as an integer. An integer can serialize automatically so the program works.

To avoid a bit of wasted effort, the program also flags the Color property with the XmlIgnore attribute so the serializer ignores it completely.

The following shows the revised Polyline class.

public class Polyline
{
[XmlIgnore] public Color Color = Color.Black;
public int Thickness = 1;
public DashStyle DashStyle = DashStyle.Solid;
public List<Point> Points = new List<Point>();

// Get or set the color as an ARGB value.
public int ToArgb
{
get { return this.Color.ToArgb(); }
set { Color = Color.FromArgb(value); }
}

public void Draw(Graphics gr)
{
using (Pen the_pen = new Pen(Color, Thickness))
{
the_pen.DashStyle = DashStyle;
if (DashStyle == DashStyle.Custom)
{
the_pen.DashPattern = new float[] { 10, 2 };
}
gr.DrawLines(the_pen, Points.ToArray());
}
}
}

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments

Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.