GrandMasterFlush
GrandMasterFlush

Reputation: 6409

Drawing lines with GDI - Invalidate() / onPaint problem

I've been learning how to use GDI but am having difficulty understanding how Invalidate() and overriding the onPaint event work and seem to be going round in circles.

I have the following code

private void DrawLine()
{
     System.Drawing.Pen myPen = new System.Drawing.Pen(System.Drawing.Color.Red);
     System.Drawing.Graphics formGraphics;
     formGraphics = this.CreateGraphics();
     formGraphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
     formGraphics.DrawLine(myPen, mouseDown.X, mouseDown.Y, mouseUp.X, mouseUp.Y);
     myPen.Dispose();
     formGraphics.Dispose();
}

protected override void OnPaint(PaintEventArgs e)
{
     DrawLine();
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
     mouseDown = e.Location;

}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
     mouseUp = e.Location;           
}

However, the only way I can get the line I've just drawn to appear is to call Invalidate() manually, and when I do it clears any previous lines. Can anyone tell me where I'm going wrong with this please?

Upvotes: 1

Views: 2594

Answers (2)

horiatu
horiatu

Reputation: 392

Make your DrawLine take a Graphics parameter:

public void DrawLine(Graphics g) { 
//...
}

In OnPaint, utilize the Graphics from e:

protected override void OnPaint(PaintEventArgs e)
{
     DrawLine(e.Graphics);
}

In MouseUp call again DrawLine with the Graphics object from the Background image of the form:

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
     mouseUp = e.Location;   
     DrawLine(Graphics.FromImage(BackgroundImage));  
     Invalidate();
}

Add a MouseMove method:

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
     mouseUp = e.Location;   
     Invalidate();
}

Optional, for clarity, rename mouseDown to StartPoint and mouseUp - EndPoint.

Upvotes: 1

LarsTech
LarsTech

Reputation: 81620

Change it to this:

Bitmap bmp = new Bitmap(256, 256);

protected override void OnPaint(PaintEventArgs e)
{
  e.Graphics.DrawImage(bmp, new Point(0, 0));
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
  mouseDown = e.Location;
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
   mouseUp = e.Location;
   using (Graphics g = Graphics.FromImage(bmp))
   {
     g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
     g.DrawLine(Pens.Red, mouseDown.X, mouseDown.Y, mouseUp.X, mouseUp.Y);
   }
   this.Invalidate();           
}

The OnPaint method provides the graphic canvas that you use to draw. Very rarely, in fact, do you ever need to call CreateGraphics yourself. The Invalidate() call on MouseUp tells your control to call the OnPaint event.

Upvotes: 1

Related Questions