You need to have two drawing calls:
-
One for the non-persistent line that follows the cursor in the
MouseMove
usingsomeControls.CreateGraphics
-
the other for the persisting line, triggered in the
MouseUp
, where- you store the coordinates and
- call
Invalidate
on your canvas control and - draw in the
Paint
event of your canvas using itse.Graphics
object.
Here is a minimal example code:
List<Point> allPoints = new List<Point>();
Point mDown = Point.Empty;
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
mDown = e.Location;
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
allPoints.Add(e.Location);
pictureBox1.Invalidate();
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left))
{
pictureBox1.Refresh();
using (Graphics G = pictureBox1.CreateGraphics())
G.DrawLine(Pens.Red, mDown, e.Location);
}
}
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if (allPoints.Count > 1) e.Graphics.DrawLines(Pens.Black, allPoints.ToArray());
}
Note that this uses a PictureBox
as the canvas control. It is the control meant for this kind of interaction. Your code seems to draw onto the desktop, which doesn’t belong to you. Drawing onto it in a persistent manner is not anything like what you would do with the/any Paint application.
Also note that my example stores a list of points and draws them as one non-closed Polyline. To draw them closed exchange DrawLines
for DrawPolygon
! To draw several such polylines or polygons you need to..
- ..decide on the user interface for it, maybe add segment points only while the control-key is pressed and otherwise finish the current polyline
- store the points in a
List<List, Point>>
Also note that this is one of the rare examples where using control.CreateGraphics
is called for, as you actually do want a non-persistent drawing while the user moves the mouse.
In most other cases the Winforms graphics basic rule #1 applies:
Never use control.CreateGraphics
! Never try to cache a Graphics
object! Either draw into a Bitmap bmp
using a Graphics g = Graphics.FromImage(bmp)
or in the Paint
event of a control, using the e.Graphics
parameter..