Copy and paste scribble data in C#


[scribble]

The example Save and restore pictures drawn by the user in C# shows how to make a simple drawing program. The example Copy and paste objects to the clipboard in C# shows how to copy objects to the clipboard. This example combines the two examples to make a scribble program that lets you copy and paste drawings.

The key is to make a single variable hold the entire drawing and mark it as serializable. Then you can copy instances of that class to the clipboard.

This example stores drawing information in the following Polyline class.

[Serializable()]
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 Argb
    {
        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());
        }
    }
}

The only really important part here is that the class is marked with the Serializable attribute.

The main program stores a series of Polyline objects in the following list.

// The polylines we draw.
private List<Polyline> Polylines = new List<Polyline>();

The following code copies the current drawing to the clipboard.

// Copy the scribble to the clipboard.
private void mnuEditCopy_Click(object sender, EventArgs e)
{
    Clipboard.SetDataObject(Polylines);
}

The following code pastes the drawing in the clipboard.

// Paste a scribble from the clipboard.
private void mnuEditPaste_Click(object sender, EventArgs e)
{
    IDataObject data_object = Clipboard.GetDataObject();
    if (data_object.GetDataPresent(Polylines.GetType()))
    {
        Polylines = (List<Polyline>)data_object.GetData(
            Polylines.GetType());
        if (Polylines == null) Polylines = new List<Polyline>();
        picCanvas.Refresh();
    }
}

This code uses the clipboard’s GetDataObject method to get the clipboard’s data object. If that object’s GetDataPresent method indicates that a List<Polyline> is present, the code uses the data object’s GetData method to get it. It converts the returned generic object into a List<Polyline>, saves the result in the program’s Polylines variable, and redraws.

You can use the same technique to copy and paste complex data structures. Just be sure to save all of the data in a single object (which may be very complex) and that the class is marked serializable.


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in drawing, graphics and tagged , , , , , , , , , , . Bookmark the permalink.

2 Responses to Copy and paste scribble data in C#

  1. Eddie Bole says:

    Hi Rod.

    Just wondering how one would add some option buttons to choose from 3 line type options: vertical polylines, horizontal polylines and freehand polylines. Also, is there a way to anti alias or or adjust the smoothness of a freehand drawn polyline? I made and uploaded some code in vb6 to planetsourcecode (CodeId=75086&lngWId=1) that draws vertical and horizontal axis scale lines so I wondered how this could be done to your csharp program? In vb6 I just kept either the x or y ordinate to a constant value (equal to the initial click point value) while varying the other ordinate value.

    Regards
    Eddie Bole

    • RodStephens says:

      You could do vertical and horizontal segments more or less as you have done in VB 6. Keep the X or Y coordinate fixed as the user moves the mouse. Some drawing programs let you use the Shift key to do this. When you move the mouse while Shift is pressed, the program compares the mouse’s X and Y coordinates to those of the previous point and keeps the coordinate that is closest fixed. For example, if the two points’ X coordinates differ by 10 and their Y coordinates differ by 120, then the program sets the new point’s X coordinate equal to the previous point’s X coordinate. It then updates the display to show the new line segment.

      This might be a bit tricky with this program because the user drags to scribble. It might work better if you use two buttons, say Shift/Alt or F/F3 to draw vertically or horizontally. Or if you click repeatedly to pick individual points, click and drag to scribble, and double-click to finish drawing. You might experiment with Microsoft Word’s drawing canvas drawing tool to see that style.

      Anti-aliasing is as easy as setting the Graphics object's SmoothingMode property. If you mean you want to draw a smooth curve so its sides aren't flat and connected with sharp corners, look at the DrawCurve method. See these posts:

      Draw a smooth curve connecting points in C#
      Change tension for a smooth curve in C#

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.