我创建了一个自定义控件,覆盖了它的paint事件。当我尝试处理我创建的图形时,它们就会从屏幕上消失。我不需要在自定义控件中使用dispose吗?
编辑:我已经添加了一个代码段。为什么我不能处理从PaintEventArgs创建的dc图形对象?我需要处理它吗?
class canvas : Control
{
PointF mouseDown;
float newX;
float newY;
float zoomFactor = 1F;
Graphics _dc;
public canvas()
{
this.DoubleBuffered = true;
mouseDown = new PointF(0F, 0F);
this.Paint += new PaintEventHandler(ctrl_Paint);
}
private void ctrl_Paint(object sender, PaintEventArgs e)
{
Graphics dc = e.Graphics;
_dc = dc;
dc.SmoothingMode = SmoothingMode.AntiAlias;
Color gridColor = Color.FromArgb(230, 230, 230);
Pen gridPen = new Pen(gridColor, 1);
float offX = (float)((Math.Sqrt(Math.Pow(newX, 2)) % (30 * zoomFactor)));
float offY = (float)((Math.Sqrt(Math.Pow(newY, 2)) % (30 * zoomFactor)));
for (float y = offY; y < this.Height; y = y + 30 * zoomFactor)
{
dc.DrawLine(gridPen, 0, y, this.Width, y);
}
for (float x = offX; x < this.Width; x = x + 30 * zoomFactor)
{
dc.DrawLine(gridPen, x, 0, x, this.Height);
}
dc.TranslateTransform(newX, newY);
dc.ScaleTransform(zoomFactor, zoomFactor, MatrixOrder.Prepend);
float XPosition = 10;
float YPosition = 10;
float CornerRadius = 5;
float Width = 50;
float Height = 50;
Color BoxColor = Color.FromArgb(0, 0, 0);
Pen BoxPen = new Pen(BoxColor, 2);
GraphicsPath Path = new GraphicsPath();
Path.AddLine(XPosition + CornerRadius, YPosition, XPosition + Width - (CornerRadius * 2), YPosition);
Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition, CornerRadius * 2, CornerRadius * 2, 270, 90);
Path.AddLine(XPosition + Width, YPosition + CornerRadius, XPosition + Width, YPosition + Height - (CornerRadius * 2));
Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
Path.AddLine(XPosition + Width - (CornerRadius * 2), YPosition + Height, XPosition + CornerRadius, YPosition + Height);
Path.AddArc(XPosition, YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
Path.AddLine(XPosition, YPosition + Height - (CornerRadius * 2), XPosition, YPosition + CornerRadius);
Path.AddArc(XPosition, YPosition, CornerRadius * 2, CornerRadius * 2, 180, 90);
Path.CloseFigure();
dc.DrawPath(BoxPen, Path);
LinearGradientBrush lgb = new LinearGradientBrush(new PointF(XPosition + (Width / 2), YPosition), new PointF(XPosition + (Width / 2), YPosition + Height), Color.RosyBrown, Color.Red);
dc.FillPath(lgb, Path);
}
}
答案 0 :(得分:9)
如果你没有创建图形对象,则不应该将其丢弃,所以如果你的签名是protected override void OnPaint(PaintEventArgs e)
,你就不会处理e.Graphics。
但是,如果在OnPaint处理程序中创建图形对象,则需要对其进行处理。
一般的经验法则(并且它是经验法则而非法则)如果您没有从Graphics.FromXxxxx()
获取对象,则不需要调用Dispose。
编辑以反映您发布的代码
您不需要处理Grapics对象,因为它是作为参数传递给您的,但是您实际上并没有覆盖控件的paint事件。这是正确的方法。
class canvas : Control
{
PointF mouseDown;
float newX;
float newY;
float zoomFactor = 1F;
public canvas()
{
this.DoubleBuffered = true;
mouseDown = new PointF(0F, 0F);
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics dc = e.Graphics;
dc.SmoothingMode = SmoothingMode.AntiAlias;
Color gridColor = Color.FromArgb(230, 230, 230);
Pen gridPen = new Pen(gridColor, 1);
float offX = (float)((Math.Sqrt(Math.Pow(newX, 2)) % (30 * zoomFactor)));
float offY = (float)((Math.Sqrt(Math.Pow(newY, 2)) % (30 * zoomFactor)));
for (float y = offY; y < this.Height; y = y + 30 * zoomFactor)
{
dc.DrawLine(gridPen, 0, y, this.Width, y);
}
for (float x = offX; x < this.Width; x = x + 30 * zoomFactor)
{
dc.DrawLine(gridPen, x, 0, x, this.Height);
}
dc.TranslateTransform(newX, newY);
dc.ScaleTransform(zoomFactor, zoomFactor, MatrixOrder.Prepend);
float XPosition = 10;
float YPosition = 10;
float CornerRadius = 5;
float Width = 50;
float Height = 50;
Color BoxColor = Color.FromArgb(0, 0, 0);
Pen BoxPen = new Pen(BoxColor, 2);
GraphicsPath Path = new GraphicsPath();
Path.AddLine(XPosition + CornerRadius, YPosition, XPosition + Width - (CornerRadius * 2), YPosition);
Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition, CornerRadius * 2, CornerRadius * 2, 270, 90);
Path.AddLine(XPosition + Width, YPosition + CornerRadius, XPosition + Width, YPosition + Height - (CornerRadius * 2));
Path.AddArc(XPosition + Width - (CornerRadius * 2), YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 0, 90);
Path.AddLine(XPosition + Width - (CornerRadius * 2), YPosition + Height, XPosition + CornerRadius, YPosition + Height);
Path.AddArc(XPosition, YPosition + Height - (CornerRadius * 2), CornerRadius * 2, CornerRadius * 2, 90, 90);
Path.AddLine(XPosition, YPosition + Height - (CornerRadius * 2), XPosition, YPosition + CornerRadius);
Path.AddArc(XPosition, YPosition, CornerRadius * 2, CornerRadius * 2, 180, 90);
Path.CloseFigure();
dc.DrawPath(BoxPen, Path);
LinearGradientBrush lgb = new LinearGradientBrush(new PointF(XPosition + (Width / 2), YPosition), new PointF(XPosition + (Width / 2), YPosition + Height), Color.RosyBrown, Color.Red);
dc.FillPath(lgb, Path);
}
}
我还删除了_dc
,因为当你不在OnPaint函数中时,你不应该编辑Graphics对象。
答案 1 :(得分:0)
如果没有一个例子,很难确切说出问题的确切位置,但我可以猜到:
在重写的OnPaint事件中,有一个参数PaintEventArgs。你应该对这个参数的Graphics对象执行所有绘图,你很高兴。这应该会让你的图形坚持下去。
答案 2 :(得分:-1)
您应该在自定义控件中部署实现IDisposable
接口的任何控件。确保您的自定义控件也实现了此接口(添加Dispose()
方法的实现),以便您正确处理其中的控件(调用它们的Dispose()
方法)。