C#:是否有必要在自定义控件中处理图形元素?

我创建了一个自定义控件,覆盖了它的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); } } 

如果你没有创建图形对象,你就不应该处理它,所以如果你的function签名是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对象。

没有一个例子,很难准确说出phoblem的位置,但我可以猜到:

在重写的OnPaint事件中,有一个参数PaintEventArgs。 你应该对这个参数的Graphics对象执行所有绘图,你很高兴。 这应该让你的图形坚持下去。

您应该在自定义控件中部署实现IDisposable接口的任何控件。 确保您的自定义控件也实现了此接口(添加Dispose()方法的实现),以便正确处理其中的控件(调用它们的Dispose()方法)。