What is the proper way to draw a line with mouse in C#

Primoz picture Primoz · Nov 12, 2010 · Viewed 9.1k times · Source

This is my drawing code to draw a custom line with mouse onto a Chart. Can you please help me to do it proper way ?

namespace Grafi
    {
        public partial class Form1 : Form
        {

            bool isDrawing = false;
            Point prevPoint;

            public Form1()
            {
                InitializeComponent();
            }

            private void chartTemperature_MouseDown(object sender, MouseEventArgs e)
            {
                isDrawing = true;
                prevPoint = e.Location;
            }

            private void chartTemperature_MouseMove(object sender, MouseEventArgs e)
            {
                Pen p = new Pen(Color.Red, 2); 
                if (isDrawing)
                {
                    Graphics g = chartTemperature.CreateGraphics();    
                    g.DrawLine(p, prevPoint, e.Location);
                    prevPoint = e.Location;

                    numOfMouseEvents = 0;              
                }
                p.Dispose();
            }

            private void chartTemperature_MouseUp(object sender, MouseEventArgs e)
            {
                isDrawing = false;
            }
        }
    }

Problem is that when I resize form my line disappers. It disappers whenever onPaint event is raised.

Answer

Paul Sasik picture Paul Sasik · Nov 12, 2010

Try this... It is a stroke drawing method, implemented very simply and as close to your own code as possible. Stokes are individual collections of mouse movements. Every mouse move between down and up is recorded as a stroke, all the strokes are collected and then redrawn whenever the paint event is fired. This example is simple but could be a good starting point.

Note that you will have to add the paint handler for your chart object.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Grafi
{
    public partial class Form1 : Form
    {
        bool isDrawing;
        // our collection of strokes for drawing
        List<List<Point>> _strokes = new List<List<Point>>();
        // the current stroke being drawn
        List<Point> _currStroke;
        // our pen
        Pen _pen = new Pen(Color.Red, 2); 

        public Form1()
        {
            InitializeComponent();
        }

        private void chartTemperature_MouseDown(object sender, MouseEventArgs e)
        {
            isDrawing = true;
            // mouse is down, starting new stroke
            _currStroke = new List<Point>();
            // add the initial point to the new stroke
            _currStroke.Add(e.Location);
            // add the new stroke collection to our strokes collection
            _strokes.Add(_currStroke);
        }

        private void chartTemperature_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDrawing)
            {
                // record stroke point if we're in drawing mode
                _currStroke.Add(e.Location);
                Refresh(); // refresh the drawing to see the latest section
            }
        }

        private void chartTemperature_MouseUp(object sender, MouseEventArgs e)
        {
            isDrawing = false;
        }

        private void chartTemperature_Paint(object sender, PaintEventArgs e)
        {
            // now handle and redraw our strokes on the paint event
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            foreach (List<Point> stroke in _strokes.Where(x => x.Count > 1))
                e.Graphics.DrawLines(_pen, stroke.ToArray());
        }
    }
}