C#:是neccesary处置自定义控件内的图形元素的? [英] C#: Is it neccesary to dispose of a graphics element inside a custom control?

查看:165
本文介绍了C#:是neccesary处置自定义控件内的图形元素的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建一个自定义的控制,覆盖它的Paint事件。当我尝试处理图形的创建,他们只是从屏幕上消失。不要我需要使用配置在自定义控件



编辑:我已经包含了代码段。为什么我不能处理直流图形对象,从PaintEventArgs的创造?我是否需要处理它



 类画布:控制
{

的PointF MOUSEDOWN;

浮动下一页末;
浮动newy指定;
浮动zoomFactor = 1F;

图形_dc;

公共帆布()
{
this.DoubleBuffered = TRUE;
MOUSEDOWN =新的PointF(0F,0F);
this.Paint + =新PaintEventHandler(ctrl_Paint);
}

私人无效ctrl_Paint(对象发件人,PaintEventArgs的E)
{


图形DC = e.Graphics;
_dc = DC;

dc.Smoothi​​ngMode = Smoothi​​ngMode.AntiAlias​​;

色彩gridColor = Color.FromArgb(230,230,230);
笔gridPen =新朋(gridColor,1);

浮动offX =(浮点)((的Math.sqrt(Math.Pow(下一页末,2))%(30 * zoomFactor)));
浮动offY =(浮点)((的Math.sqrt(Math.Pow(newy指定,2))%(30 * zoomFactor)));

为(浮动Y = offY; Y< this.Height; Y = Y + 30 * zoomFactor)
{
dc.DrawLine(gridPen,0,Y,这.WIDTH,Y);
}
为(浮动X = offX; X< this.Width; X = X + 30 * zoomFactor)
{
dc.DrawLine(gridPen,X,0, X,this.Height);
}

dc.TranslateTransform(下一页末,newy指定);
dc.ScaleTransform(zoomFactor,zoomFactor,MatrixOrder.Prepend);

浮动xPosition位置= 10;
浮动YPosition = 10;
浮动CornerRadius = 5;
浮动宽度= 50;
浮动高度= 50;

色彩BoxColor = Color.FromArgb(0,0,0);
笔BoxPen =新朋(BoxColor,2);

GraphicsPath的路径=新的GraphicsPath();

Path.AddLine(xPosition位置+ CornerRadius,YPosition xPosition位置+宽度 - (CornerRadius * 2),YPosition);
Path.AddArc(xPosition位置+宽度 - (CornerRadius * 2),YPosition,CornerRadius * 2,CornerRadius * 2,270,90);
Path.AddLine(xPosition位置+宽度,YPosition + CornerRadius xPosition位置+宽度,YPosition +高度 - (CornerRadius * 2));
Path.AddArc(xPosition位置+宽度 - (CornerRadius * 2),YPosition +高度 - (CornerRadius * 2),CornerRadius * 2,CornerRadius * 2,0,90);
Path.AddLine(xPosition位置+宽度 - (CornerRadius * 2),YPosition +身高xPosition位置+ CornerRadius,YPosition +高);
Path.AddArc(xPosition位置,YPosition +高度 - (CornerRadius * 2),CornerRadius * 2,CornerRadius * 2,90,90);
Path.AddLine(xPosition位置,YPosition +高度 - (CornerRadius * 2),xPosition位置,YPosition + CornerRadius);
Path.AddArc(xPosition位置,YPosition,CornerRadius * 2,CornerRadius * 2,180,90);

Path.CloseFigure();

dc.DrawPath(BoxPen,路径);

一个LinearGradientBrush LGB =新一个LinearGradientBrush(新的PointF(xPosition位置+(宽度/ 2),YPosition),新的PointF(xPosition位置+(宽度/ 2),YPosition +高度),Color.RosyBrown,颜色。红);

dc.FillPath(LGB,路径);

}
}


解决方案

如果你没有创建图形对象,你不应该处理它,所以如果你的函数签名是保护覆盖无效的OnPaint(PaintEventArgs的E)你不会处理即图形。



然而,如果你创建了OnPaint处理,您将需要处理它的图形对象。



一般的经验法则(它是拇指不是一个法律规则),如果你没有从让你的对象 Graphics.FromXxxxx()你不需要调用Dispose



您已经发布修改,以反映代码



您不需要该Grapics对象的处理,因为它传递给你作为一个参数,但你实际上并没有覆盖你的控制研究Paint事件。这是做正确的方式。



 类画布:控制
{

鼠标按下的PointF;

浮动下一页末;
浮动newy指定;
浮动zoomFactor = 1F;


公共帆布()
{
this.DoubleBuffered = TRUE;
MOUSEDOWN =新的PointF(0F,0F);
}

保护覆盖无效的OnPaint(PaintEventArgs的E)
{
base.OnPaint(E);
图形DC = e.Graphics;

dc.Smoothi​​ngMode = Smoothi​​ngMode.AntiAlias​​;

色彩gridColor = Color.FromArgb(230,230,230);
笔gridPen =新朋(gridColor,1);

浮动offX =(浮点)((的Math.sqrt(Math.Pow(下一页末,2))%(30 * zoomFactor)));
浮动offY =(浮点)((的Math.sqrt(Math.Pow(newy指定,2))%(30 * zoomFactor)));

为(浮动Y = offY; Y< this.Height; Y = Y + 30 * zoomFactor)
{
dc.DrawLine(gridPen,0,Y,这.WIDTH,Y);
}
为(浮动X = offX; X< this.Width; X = X + 30 * zoomFactor)
{
dc.DrawLine(gridPen,X,0, X,this.Height);
}

dc.TranslateTransform(下一页末,newy指定);
dc.ScaleTransform(zoomFactor,zoomFactor,MatrixOrder.Prepend);

浮动xPosition位置= 10;
浮动YPosition = 10;
浮动CornerRadius = 5;
浮动宽度= 50;
浮动高度= 50;

色彩BoxColor = Color.FromArgb(0,0,0);
笔BoxPen =新朋(BoxColor,2);

GraphicsPath的路径=新的GraphicsPath();

Path.AddLine(xPosition位置+ CornerRadius,YPosition xPosition位置+宽度 - (CornerRadius * 2),YPosition);
Path.AddArc(xPosition位置+宽度 - (CornerRadius * 2),YPosition,CornerRadius * 2,CornerRadius * 2,270,90);
Path.AddLine(xPosition位置+宽度,YPosition + CornerRadius xPosition位置+宽度,YPosition +高度 - (CornerRadius * 2));
Path.AddArc(xPosition位置+宽度 - (CornerRadius * 2),YPosition +高度 - (CornerRadius * 2),CornerRadius * 2,CornerRadius * 2,0,90);
Path.AddLine(xPosition位置+宽度 - (CornerRadius * 2),YPosition +身高xPosition位置+ CornerRadius,YPosition +高);
Path.AddArc(xPosition位置,YPosition +高度 - (CornerRadius * 2),CornerRadius * 2,CornerRadius * 2,90,90);
Path.AddLine(xPosition位置,YPosition +高度 - (CornerRadius * 2),xPosition位置,YPosition + CornerRadius);
Path.AddArc(xPosition位置,YPosition,CornerRadius * 2,CornerRadius * 2,180,90);

Path.CloseFigure();

dc.DrawPath(BoxPen,路径);

一个LinearGradientBrush LGB =新一个LinearGradientBrush(新的PointF(xPosition位置+(宽度/ 2),YPosition),新的PointF(xPosition位置+(宽度/ 2),YPosition +高度),Color.RosyBrown,颜色。红);

dc.FillPath(LGB,路径);

}
}



我也删除 _dc ,你不应该被编辑时你是不是的OnPaint函数内部的Graphics对象。


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 dispose in custom controls?

EDIT: I've included a code snippet. Why can't i dispose the dc graphics object, created from the PaintEventArgs? Do i need to dispose it?

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

        }
}

解决方案

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.

这篇关于C#:是neccesary处置自定义控件内的图形元素的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆