Let the user draw lines in C#

[draw lines]

This example lets the user click and draw to draw lines. To make working with lines easier, the program uses the following Segment class.

class Segment
    public Pen Pen;
    public Point Point1, Point2;

    public Segment(Pen pen, Point point1, Point point2)
        Pen = pen;
        Point1 = point1;
        Point2 = point2;

    public void Draw(Graphics gr)
        gr.DrawLine(Pen, Point1, Point2);

This class simply stores a pen and the segment’s end points. The Draw method draws the segment on a Graphics object.

The program uses the following form-level variables to let the user draw lines.

private List<Segment> Segments = new List<Segment>();
private Segment NewSegment = null;

The Segments list holds Segment objects that were created in the past. NewSegment represents a new Segment while the user is drawing it. This variable is null when the user is not drawing a new segment.

Line drawing begins when the user presses the mouse down over the picCanvas PictureBox making the following event handler execute.

// Start drawing a new segment.
private void picCanvas_MouseDown(object sender, MouseEventArgs e)
    NewSegment = new Segment(Pens.Blue, e.Location, e.Location);

This code sets NewSegment to a new Segment object with a blue pen. It sets both of the new segment’s end points to the mouse’s current location.

The method then refreshes the picCanvas PictureBox to make the following Paint event handler execute to display the new segment (and any old segments).

// Draw the segments.
private void picCanvas_Paint(object sender, PaintEventArgs e)
    e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

    // Draw existing segments.
    foreach (Segment segment in Segments)

    // Draw the new segment if there is one.
    if (NewSegment != null)

This code clears the Graphics object and sets its SmoohingMode. It then loops through the objects in the Segments list and calls their Draw methods to make them draw themselves. Finally, if NewSegment isn’t null, the code calls that object’s Draw method to make it draw itself.

When the user moves the mouse over the picCanvas PictureBox, the following event handler executes.

// Continue drawing the new segment.
private void picCanvas_MouseMove(object sender, MouseEventArgs e)
    if (NewSegment == null) return;
    NewSegment.Point2 = e.Location;

This method first checks whether NewSegment is null. If it is null, then the user is not drawing a new segment. In that case, the code simply returns.

If NewSegment is not null, the code updates the new segment’s second end point to the mouse’s current location. It then refreshes the PictureBox to make it redraw the segments to show the new one’s updated position.

When the user releases the mouse, the following event handler executes.

// Finish drawing the new segment.
private void picCanvas_MouseUp(object sender, MouseEventArgs e)
    if (NewSegment == null) return;

    NewSegment.Pen = Pens.Black;
    NewSegment = null;

Like the MouseMove event handler, this one checks whether NewSegment is null and returns if the user is not drawing a new segment. It then sets the new segment’s pen to black and adds it to the Segments list. It sets NewSegment to null to indicate that we are done drawing the new segment and then refreshes the PictureBox to redraw the lines.

Download Example   Follow me on Twitter   RSS feed   Donate

About RodStephens

Rod Stephens is a software consultant and author who has written more than 30 books and 250 magazine articles covering C#, Visual Basic, Visual Basic for Applications, Delphi, and Java.
This entry was posted in drawing, events, graphics and tagged , , , , , , , , , , , . Bookmark the permalink.

5 Responses to Let the user draw lines in C#

  1. Marcelo Caparoz says:

    It is possible to calculate real metrics between to points, in milimeters for example?
    anc calculate angle between 3 vertex?

    • RodStephens says:

      Calculating real distances is a bit tricky. First you need to know the current DPI (dots per inch) resolution. Normally that is 96 pixels per inch for a monitor. Unfortunately that is logical pixels per inch. The true pixels per inch depends on the size of the monitor and your current screen settings.

      See the MSDN discussion post Get real image size in centimeters for a discussion.

      Probably your best bet is to measure a line on your screen and use it and its length in pixels to get a scale factor that you can use after that. And don’t change your screen settings.

      To find the angle between two lines, see the GetAngle method in my post Determine whether a point is inside a polygon in C#.

  2. Patrick says:

    Great help in drawing lines on a bitmap. Have tried several approaches (unsuccessfully) to save the picturebox image with line to a bitmap. How do I accomplish that?

  3. Saurav Bhattacharjee says:

    It is a great help from you to show the correct direction in solving the issue. Thanks a lot.

Comments are closed.