我一直在学习如何使用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(),当我这样做时会清除之前的任何行。有谁能告诉我,我在哪里出错?
答案 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。