C#: Is it necessary to dispose of a graphics element inside a custom control?

前端 未结 3 1811
后悔当初
后悔当初 2021-01-20 15:31

I\'ve created a custom control, overridden it\'s paint event. When I try to dispose of the graphics I create they just disappear from the screen. Don\'t I need to use dispos

相关标签:
3条回答
  • 2021-01-20 16:00

    You should be disposing any controls within your custom control that implement the IDisposable interface. Ensure that your custom control implements this interface as well (add an implementation of the Dispose() method) so that you dispose of the controls within it properly (calling their Dispose() methods).

    0 讨论(0)
  • 2021-01-20 16:01

    If you did not create the graphics object you should not dispose it, so if you function signature is protected override void OnPaint(PaintEventArgs e) you would NOT dispose e.Graphics.

    However if you create a graphics object in the OnPaint handler you will need to dispose it.

    General rule of thumb (and it is a rule of thumb not a law) if you did not get your object from a Graphics.FromXxxxx() you do not need to call Dispose.

    EDIT to reflect code you have posted

    You do not need to dispose of the Grapics object because it was passed to you as a argument, however you are not actually overriding the paint event for your controll. This is the correct way to do it.

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

    I also removed _dc as you should not be editing the Graphics object when you are not inside the OnPaint function.

    0 讨论(0)
  • 2021-01-20 16:12

    Without an example it's hard to say exactly where the phoblem is, but I can guess:

    In your overriden OnPaint event, there's a parameter PaintEventArgs. You should perform all drawing onto this parameter's Graphics object, and you're good to go. That should make your graphics stick.

    0 讨论(0)
提交回复
热议问题