使用GDI绘制线条 - Invalidate()/ onPaint问题

时间:2011-09-16 11:29:23

标签: c# gdi

我一直在学习如何使用GDI,但我很难理解Invalidate()和覆盖onPaint事件是如何工作的,而且似乎是围成一圈。

我有以下代码

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;           
}

然而,我能够获得我刚刚绘制的线的唯一方法是手动调用Invalidate(),当我这样做时会清除之前的任何行。有谁能告诉我,我在哪里出错?

2 个答案:

答案 0 :(得分:1)

将其更改为:

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();           
}

OnPaint方法提供了用于绘制的图形画布。事实上,你很少需要自己调用CreateGraphics。 MouseUp上的Invalidate()调用告诉您的控件调用OnPaint事件。

答案 1 :(得分:1)

让DrawLine采用Graphics参数:

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

在OnPaint中,使用e:

中的图形
protected override void OnPaint(PaintEventArgs e)
{
     DrawLine(e.Graphics);
}

在MouseUp中,再次使用形式的背景图像中的Graphics对象调用DrawLine:

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

添加MouseMove方法:

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

可选,为清楚起见,将mouseDown重命名为StartPoint和mouseUp - EndPoint。