// 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()); } } }
12/18/2010 2:59 AMRichard Moss wrote:
"The example Display an end user license agreement the first time the user runs a program in C# explains how to let the user draw curves"
"The example Display an end user license agreement the first time the user runs a program in C# explains how to let the user draw curves"
Erm... it does?
Reply to this
Oops! I've fixed that reference. Thanks for pointing this out.
Reply to this