C#:是否有必要处理自定义控件中的图形元素? [英] C#: Is it necessary to dispose of a graphics element inside a custom control?

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

问题描述

我创建了一个自定义控件,重写了它的绘画事件。当我尝试处理我创建的图形时,它们只是从屏幕上消失。我不需要在自定义控件中使用配置吗?



编辑:我已经包含了一段代码片段。为什么我不能处理从PaintEventArgs创建的直流图形对象?

  class canvas:Control 
{

PointF mouseDown;

float newX;
float newY;
float zoomFactor = 1F;

图形_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;

颜色gridColor = Color.FromArgb(230,230,230);
Pen gridPen =新笔(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 {
dc.DrawLine(gridPen,0,y,this .Width,y); (float x = offX; x {
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 =新笔(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。红);

dc.FillPath(lgb,Path);


$ b


解决方案

如果您没有创建图形对象,则不应该将其处理,所以如果函数签名是 protected override void OnPaint(PaintEventArgs e),则不会处理e。图形。



然而,如果您在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);
图形dc = e.Graphics;

dc.SmoothingMode = SmoothingMode.AntiAlias;

颜色gridColor = Color.FromArgb(230,230,230);
Pen gridPen =新笔(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 {
dc.DrawLine(gridPen,0,y,this .Width,y); (float x = offX; x {
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 =新笔(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。红);

dc.FillPath(lgb,Path);


$ b $ / code>

我也删除了 _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#:是否有必要处理自定义控件中的图形元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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