The example Draw and move line segments in C# shows how to build a simple line editor. This example adds the ability to save and restore drawings.
The first step is to save all of the drawing information in a single object. You can save the information on an array or list, but it’s probably easiest if you save everything in an object from a class that you define.
The previous version of the program stored the end points of the line segments in two lists of points. This example uses the following class to represent a drawing.
// A class to serialize and deserialize drawings. public class Drawing { public List<Point> Pt1 = new List<Point>(); public List<Point> Pt2 = new List<Point>(); }
The main program uses the following object to store the lines’ points.
// The points that make up the line segments. private Drawing TheDrawing = new Drawing();
Most of the main program’s code is similar to the previous version except it uses this object instead of separate point lists.
The following code shows how the program saves a drawing.
// Save a serialization of the drawing. private void mnuFileSaveAs_Click(object sender, EventArgs e) { if (sfdSave.ShowDialog() == DialogResult.OK) { // Serialize. XmlSerializer xml_serializer = new XmlSerializer(TheDrawing.GetType()); using (StreamWriter stream_writer = new StreamWriter(sfdSave.FileName)) { xml_serializer.Serialize(stream_writer, TheDrawing); stream_writer.Close(); } } }
This code displays a SaveFileDialog. If the user selects a file and clicks Save, the code create an XmlSerializer to work with the type of the object TheDrawing. It creates a StreamWriter to write into the desired file and then uses the serializer to write the drawing object’s serialization into the file.
The following code shows how the program loads a saved drawing.
// Load a serialization of a drawing. private void mnuFileOpen_Click(object sender, EventArgs e) { if (ofdLoad.ShowDialog() == DialogResult.OK) { try { XmlSerializer xml_serializer = new XmlSerializer(TheDrawing.GetType()); using (FileStream file_stream = new FileStream(ofdLoad.FileName, FileMode.Open)) { Drawing new_drawing = (Drawing)xml_serializer.Deserialize(file_stream); TheDrawing = new_drawing; picCanvas.Refresh(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } }
This code displays a OpenFileDialog. If the user selects a file and clicks Open, the code create an XmlSerializer to work with the type of the object TheDrawing. It creates a StreamWriter to read from the selected file and then uses the serializer to deserialize the data in the file, converting the result into a Drawing object. If all of that succeeds, the code saves the new Drawing object in the variable TheDrawing and redraws.
The code works inside a try catch block in case something goes wrong. For example, if the user selects a file that doesn’t hold a line drawing serialization or if the file is corrupted, then the code does not replace the previous drawing.




Dear Rod
Thank you for the great articles. I am wondering how to save and restore the user’s clicked coordinates on to a grid, which in turns is on a PictureBox. I have already a IList filledSq = new List(); to store the user’s clicks a grid pattern. I just want to save them and when the user wants to reopen, the program reloads the points and draw the points on the grid again.
Thanks a lot.
You could use the same approach used by this program. Create a class to hold the list of points. Then use serialization to read and write the object holding the points in and out of a file.
Dear Rod
Thank you very much for the reply. I managed to serialize the points (I also changed IList to List for filledSq; otherwise, serialize has an error) nicely. But when I deserialize, the picturebox can’t show anything. I believe it is due to the way I use “pictureBoxGrid_Paint” event, in which I draw a user selected size( handled by numericUpDownMatrixSize_ValueChanged) grid pattern (e.g. 100 x 100) and the dots are drawn by another event handler “pictureBoxGrid_MouseClick”. How do I handle the redrawing of the saved points with the correct grid size?
Thank you!!
Normally you either (1) draw in Paint or (2) draw on a bitmap and then display the bitmap in the PictureBox’s Image property. Trying to do anything else usually causes problems. For example, if you use CreateGraphics to draw when the user clicks, then you get problems if the form is resized, minimized and then restored, covered by another window, etc.
A better approach is to make a list of points and then have the Paint event handler draw them. Then when you load the saved points, you just call the PictureBox’s Refresh method and it automatically raises Paint and redraws.
That’s how the example draws its lines. Just add your code to draw points in the Paint event handler.
And don’t forget to call Refresh after you load saved points. If you don’t, then it will look like nothing has happened.
Thank you, Rod. Appreciate your help greatly. My problem was because I drew the grid in _Paint event method while the clicked dots were drawn in _MouseClick event method. I now understand I cannot even draw things in any other method except _Paint.
I have managed to work around my issue by using a global Boolean variable to check when the file open button is clicked, then drawing the dots again in _Paint event method. Not an ideal solution yet. But starting to get the hang of it. 🙂
Can you demonstrate an example code here for saving the coordinates into a text file and using the same text file again to draw the graphics. thanks
The Save As and Open Click event handlers shown above do that. Download the example program to run it and to see additional details.
If you mean you want to see what the serialized file looks like, here’s an example that contains two lines segments.
Pingback: Use command line arguments to open files in C# - C# HelperC# Helper
Hello Ron, I was wondering if there is a solution to use more type of Pens, I used your idea and tried to implement a button for Arrow End line and simple line, it works, but when I change the type and start drawing, every line gets the same attribution. Hope you will read this message and respond. Thank you 🙂
If you want to give the line different characteristics (different end caps, colors, dash patterns etc.), then you should probably make a class to represent the lines. It can save each line’s style information.
Here’s an example that does something similar using scribbles instead of lines:
Save and restore pictures drawn by the user in C#