【问题标题】:The image draws itself before I click Draw在我单击 Draw 之前,图像会自行绘制
【发布时间】:2018-10-04 08:39:16
【问题描述】:

在应用程序中,我正在尝试绘制具有用户定义的宽度和高度的形状。然后当它绘制时,我尝试修改它的笔画粗细。

像这样:

这一切都很好,直到我将它保存为一个对象并一遍又一遍地重绘它。当我再次尝试绘制某些东西,并尝试放大笔画粗细并缩小比例时,它会将绘图保留为灰色,只有当绘图被接受时才适用。 Red Line 是当前绘制的形状,而其背面的 gray 是我的问题。我还没接受呢。

代码如下:

主窗体

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        cbox_Grid.Checked =true;
        pictureBox_Canvass.Paint += draw.ShowGrid;
    }
    Draw draw = new Draw();
    Shape s = new Shape();
    Shape.Buttons buttons = new Shape.Buttons(); 
    int rX, rY, rW, rH;         //Rectangle Variables
    int strokeRect;
    private void cbox_Grid_CheckedChanged(object sender, EventArgs e)
    {
        if (cbox_Grid.Checked)
        {
            pictureBox_Canvass.Paint += draw.ShowGrid;
            pictureBox_Canvass.Paint += DrawAll;
            pictureBox_Canvass.Refresh();
        }
        else
        {
            pictureBox_Canvass.Paint += draw.ClearCanvass;
            pictureBox_Canvass.Paint += DrawAll;
            pictureBox_Canvass.Refresh();
        }
    }

    #region Shape Buttons
    private void btn_Rectangle_Click(object sender, EventArgs e)
    {
        this.tbox_Width.Text = "60";
        this.tbox_Height.Text = "30";
        buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "rectangle");
        HideButtons();
        ShowSettings();

    }

    private void btn_Square_Click(object sender, EventArgs e)
    {
        buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "square");
        this.tbox_Width.Text = "60";
        this.tbox_Height.Text = "60";
        HideButtons();
        ShowSettings();
    }

    private void btn_Circle_Click(object sender, EventArgs e)
    {
        buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "circle");
        this.tbox_Width.Text = "60";
        this.tbox_Height.Text = "60";
        HideButtons();
        ShowSettings();

    }

    private void btn_Ellipse_Click(object sender, EventArgs e)
    {
        buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "ellipse");
        this.tbox_Width.Text = "60";
        this.tbox_Height.Text = "30";
        HideButtons();
        ShowSettings();
    }

    private void btn_Triangle_Click(object sender, EventArgs e)
    {
        buttons = (Shape.Buttons)System.Enum.Parse(typeof(Shape.Buttons), "triangle");
        this.tbox_Width.Text = "60";
        this.tbox_Height.Text = "60";
        HideButtons();
        ShowSettings();
    }
    #endregion

    #region Draw Button Event
    private void btn_Draw_Click(object sender, EventArgs e)
    {
        pictureBox_Canvass.Refresh();
        if(cbox_Grid.Checked)
        {
            switch (buttons)
            {
                case Shape.Buttons.rectangle:
                    pictureBox_Canvass.Paint += draw.ShowGrid;
                    pictureBox_Canvass.Paint += DrawAll;
                    pictureBox_Canvass.Paint += DrawRect;
                    pictureBox_Canvass.Refresh();
                    break;
                case Shape.Buttons.square:

                    break;
                case Shape.Buttons.circle:

                    break;
                case Shape.Buttons.ellipse:

                    break;
                case Shape.Buttons.triangle:

                    break;
            }
        }
        else
        {
            switch (buttons)
            {
                case Shape.Buttons.rectangle:
                    pictureBox_Canvass.Paint += DrawAll;
                    pictureBox_Canvass.Paint += DrawRect;
                    pictureBox_Canvass.Refresh();
                    break;
                case Shape.Buttons.square:

                    break;
                case Shape.Buttons.circle:

                    break;
                case Shape.Buttons.ellipse:

                    break;
                case Shape.Buttons.triangle:

                    break;
            }
        }
    }
    #endregion

    #region PaintEvents
    public void DrawRect(object sender, PaintEventArgs e)
    {
        rX = (((486 / 2) - (Convert.ToInt32((Convert.ToInt32(tbox_Width.Text) * 96) / 25.4)) / 2));
        rY = (((486 / 2) - (Convert.ToInt32((Convert.ToInt32(tbox_Height.Text) * 96) / 25.4)) / 2));
        rW = (Convert.ToInt32((Convert.ToInt32(tbox_Width.Text) * 96) / 25.4));
        rH = (Convert.ToInt32((Convert.ToInt32(tbox_Height.Text) * 96) / 25.4));

        Shape shape = new Shape();
        strokeRect = trackBar_Stroke.Value;
        shape.strokeThickness = strokeRect;
        shape.acceptRectangle(Color.Red, strokeRect, new PointF(rX, rY), rW, rH, e.Graphics); 
    }
    public void AcceptRect(object sender, PaintEventArgs e)
    {
        Shape shape = new Shape();
        shape.color = Color.Gray;
        shape.strokeThickness = this.strokeRect;
        shape.points = new PointF(rX, rY);
        shape.width = rW;
        shape.height = rH;
        shape.DrawRectangle(Color.Gray, strokeRect, new PointF(rX, rY), rW, rH, e.Graphics);
        s._shapes.Add(shape);
    }
    #endregion

    public void DrawAll(object sender, PaintEventArgs e)
    {
        foreach (Shape shapes in s._shapes)
        {
            s.acceptRectangle(shapes.color, shapes.strokeThickness, shapes.points, shapes.width, shapes.height, e.Graphics);
        }
    }

    #region Accept-Reset-Cancel
    private void btn_Accept_Click(object sender, EventArgs e)
    {
        switch (buttons)
        {
            case Shape.Buttons.rectangle:
                pictureBox_Canvass.Paint += AcceptRect;
                pictureBox_Canvass.Refresh();
                break;
            case Shape.Buttons.square:

                break;
            case Shape.Buttons.circle:

                break;
            case Shape.Buttons.ellipse:

                break;
            case Shape.Buttons.triangle:

                break;
        }
        HideSettings();
        ShowButtons();

    }

    private void btn_Cancel_Click(object sender, EventArgs e)
    {

        HideSettings();
        ShowButtons();
    }

    private void btn_Reset_Click(object sender, EventArgs e)
    {
        s._shapes.Clear();
        rX = 0;
        rY = 0;
        rW = 0;
        rH = 0;
        if(cbox_Grid.Checked)
        {
            pictureBox_Canvass.Paint += draw.ClearCanvass;
            pictureBox_Canvass.Paint += draw.ShowGrid;
            pictureBox_Canvass.Refresh();
        }
        else
        {
            pictureBox_Canvass.Paint += draw.ClearCanvass;
            pictureBox_Canvass.Refresh();
        }
        HideSettings();
        ShowButtons();
    }
    #endregion
    #region Methods for Hide and Show
    public void HideButtons()
    {
        btn_Rectangle.Visible = false;
        btn_Square.Visible = false;
        btn_Ellipse.Visible = false;
        btn_Circle.Visible = false;
        btn_Triangle.Visible = false;
    }
    public void ShowButtons()
    {
        btn_Rectangle.Visible = true;
        btn_Square.Visible = true;
        btn_Ellipse.Visible = true;
        btn_Circle.Visible = true;
        btn_Triangle.Visible = true;
    }
    public void HideSettings()
    {
        btn_Draw.Visible = false;
        btn_Accept.Visible = false;
        btn_Cancel.Visible = false;
        btn_Reset.Visible = false;
        btn_Accept.Visible = false;
        trackBar_Size.Visible = false;
        trackBar_Stroke.Visible = false;
        trackBar_Corner.Visible = false;
        label_Corner.Visible = false;
        label_Height.Visible = false;
        label_Size.Visible = false;
        label_Stroke.Visible = false;
        rb_Both.Visible = false;
        rb_Height.Visible = false;
        rb_Width.Visible = false;
        tbox_Height.Visible = false;
        tbox_Width.Visible = false;
        label_Width.Visible = false;
    }
    public void ShowSettings()
    {
        btn_Draw.Visible = true;
        btn_Accept.Visible = true;
        btn_Cancel.Visible = true;
        btn_Reset.Visible = true;
        btn_Accept.Visible = true;
        trackBar_Size.Visible = true;
        trackBar_Stroke.Visible = true;
        trackBar_Corner.Visible = true;
        label_Corner.Visible = true;
        label_Height.Visible = true;
        label_Size.Visible = true;
        label_Stroke.Visible = true;
        rb_Both.Visible = true;
        rb_Height.Visible = true;
        rb_Width.Visible = true;
        tbox_Height.Visible = true;
        tbox_Width.Visible = true;
        label_Width.Visible = true;
    }
    #endregion

    #region Size Scaling
    private void trackBar_Stroke_Scroll(object sender, EventArgs e)
    {
        pictureBox_Canvass.Refresh();
        switch (buttons)
        {
            case Shape.Buttons.rectangle:
                strokeRect = trackBar_Stroke.Value;
                break;
            case Shape.Buttons.square:

                break;
            case Shape.Buttons.circle:

                break;
            case Shape.Buttons.ellipse:

                break;
            case Shape.Buttons.triangle:

                break;
        };
    }
    #endregion
    #region Stroke Scaling
    private void trackBar_Size_Scroll(object sender, EventArgs e)
    {
        switch (buttons)
        {
            case Shape.Buttons.rectangle:

                break;
            case Shape.Buttons.square:

                break;
            case Shape.Buttons.circle:

                break;
            case Shape.Buttons.ellipse:

                break;
            case Shape.Buttons.triangle:

                break;
        }
        pictureBox_Canvass.Refresh();
    }
    #endregion
}

形状类

public class Shape
{
    public Draw draw;
    public float width;
    public float height;
    public float x;
    public float y;
    public PointF points;
    public int strokeThickness;
    public Color color;
    public List<Shape> _shapes = new List<Shape>();
    public float acceptedStroke;
    public enum Buttons
    {
        rectangle, square, circle, ellipse, triangle
    }
    public void DrawRectangle(Color c, int stroke, PointF points, float w, float h,Graphics g)
    {
        this.points = points;
        this.width = w;
        this.height = h;
        this.strokeThickness = stroke;
        g.DrawRectangle(new Pen(c,stroke), points.X, points.Y,w,h);
    }
    public void acceptRectangle(Color c, int stroke, PointF points, float w, float h, Graphics g)
    {
        this.points = points;
        this.width = w;
        this.height = h;
        this.acceptedStroke = stroke;
        g.DrawRectangle(new Pen(c, stroke), points.X, points.Y, w, h);
    }
}

【问题讨论】:

    标签: c# graphics shapes


    【解决方案1】:

    在你的 Shape 类中

        //Methods
        public void DrawRectangle(Color c, int stroke, float w, float h, Graphics g, float radius)
        {
            this.width = w;
            this.height = h;
            this.strokeThickness = stroke;
            this.type = ShapeType.rectangle;
            this.radius = radius;
    
            //Centering the Shape
            PointF points = new PointF();
            //w -= strokeThickness;
            //h -= strokeThickness;
            points.X = (center.X - ((w) / 2f));
            points.Y = (center.Y - ((h) / 2f));
    
            //Aliasing for smooth graphics when drawing and resizing
            g.InterpolationMode = InterpolationMode.High;
    
            //Drawing
            RectangleF rect = new RectangleF(points.X, points.Y, w, h);
            GraphicsPath path = this.GetRoundedRect(rect, radius);
            g.DrawPath(new Pen(c, stroke), path);
        }
        public void DrawSquare(Color c, int stroke, float w, float h, Graphics g, float radius)
        {
            this.width = w;
            this.height = h;
            this.strokeThickness = stroke;
            this.type = ShapeType.square;
            this.radius = radius;
    
            //w -= strokeThickness;
            //h -= strokeThickness;
            //Centering the Shape
            PointF points = new PointF();
            points.X = (center.X - (w / 2));
            points.Y = (center.Y - (h / 2) + DefaultOffset);
    
            //Aliasing for smooth graphics when drawing and resizing
            g.InterpolationMode = InterpolationMode.High;
    
            //Drawing
            RectangleF rect = new RectangleF(points.X, points.Y, w, h);
            GraphicsPath path = this.GetRoundedRect(rect, radius);
            g.DrawPath(new Pen(c, stroke), path);
        }
        public void DrawCircle(Color c, int stroke, float w, float h, Graphics g)
        {
            this.width = w;
            this.height = h;
            this.strokeThickness = stroke;
            this.type = ShapeType.circle;
    
            PointF points = new PointF();
            //Centering the Shape
            points.X = (float)((center.X - (w/ 2)));
            points.Y = (float)((center.Y - (h / 2)));
    
            //Aliasing for smooth graphics when drawing and resizing
            g.SmoothingMode = SmoothingMode.AntiAlias;
    
            //Drawing
            RectangleF rect = new RectangleF(points.X, points.Y, w, h);
            g.DrawEllipse(new Pen(c, stroke), rect);
    
        }
        public void DrawEllipse(Color c, int stroke, float w, float h, Graphics g)
        {
            this.width = w;
            this.height = h;
            this.strokeThickness = stroke;
            this.type = ShapeType.ellipse;
    
            //Centering the Shape
            PointF points = new PointF();
            points.X = (center.X - (w / 2));
            points.Y = (center.Y - (h / 2));
    
            //Aliasing for smooth graphics when drawing and resizing
            g.SmoothingMode = SmoothingMode.AntiAlias;
    
            //Drawing
            RectangleF rect = new RectangleF(points.X, points.Y, w, h);
            g.DrawEllipse(new Pen(c, stroke), rect);
    
        }
        public void DrawTriangle(Color c, int stroke, float w, Graphics g, float radius)
        {
            this.strokeThickness = stroke;
            this.type = ShapeType.triangle;
    
            float h = (float)((w * (Math.Sqrt(3))) / 2);
            PointF points = new PointF();
            points.Y = (int)(((center.Y - h) + (h / 3f)) + DefaultOffset);
            points.X = (int)center.X - (w / 2f);
            this.size = new SizeF(w, h);
            this.location = points;
            //Calculation of the triangle points
            RectangleF rect = new RectangleF(this.location, this.size);
            PointF A = new PointF(rect.X, rect.Y + rect.Height);
            PointF B = new PointF(rect.X + (rect.Width / 2f), rect.Y);
            PointF C = new PointF(rect.Right, rect.Y + rect.Height);
    
            //Drawing
            GraphicsPath path = this.DrawRoundedTriangle(rect, A, B, C, radius);
            g.DrawPath(new Pen(c, stroke), path);
        }
        #endregion
    

    给他们打电话

    private void pictureBox_Canvass_Paint(object sender, PaintEventArgs e)
        {
            case Shape.ShapeType.rectangle:
                    shape.DrawRectangle(rectangleColor, strokeRect, rectangleWidth, rectangleHeight, e.Graphics, rectRadius);
                    break;
                case Shape.ShapeType.square:
                    shape.DrawSquare(squareColor, strokeSquare, squareWidth, squareHeight, e.Graphics, squareRadius);
                    break;
                case Shape.ShapeType.circle:
                    shape.DrawCircle(circleColor, strokeCircle, circleWidth, circleHeight, e.Graphics);
                    break;
                case Shape.ShapeType.ellipse:
                    shape.DrawEllipse(ellipseColor, strokeEllipse, ellipseWidth, ellipseHeight, e.Graphics);
                    break;
                case Shape.ShapeType.triangle:
                    shape.DrawTriangle(triangleColor, strokeTriangle, triangleWidth, e.Graphics, triangleRadius);
                    break;
        }
    

    【讨论】:

      【解决方案2】:

      事件处理程序是列表。当你这样做时:

      pictureBox_Canvass.Paint += draw.ShowGrid;
      

      您将draw.ShowGrid 添加到当您的pictureBox_Canvass 需要绘图时调用的方法列表。您不断为多个方法重复此操作,从不删除它们,因此每次您的 pictureBox_Canvass 需要重绘时,您的所有方法都会被多次调用。

      这是完全错误的。从您的代码中删除像pictureBox_Canvass.Paint += 这样的所有内容,除了您的表单构造函数。您只需要一个用于 pictureBox_Canvass 的 Paint 处理程序,它应该在您创建表单时创建,并且永远不要更改它。事实上,如果您使用 Visual Studio 设计视图,您可能已经拥有其中之一;在设计视图中单击您的图片框,然后在属性面板中双击 Paint 事件,它将打开 Paint 处理程序。

      在该处理程序中,您只需要绘制您想要的线条。您需要一个表单变量或其他东西来保存形状及其坐标。设置该变量并在您单击按钮并在 Paint 处理程序中绘制它时调用 pictureBox_Canvass.Invalidate()

      一个非常简单的例子是How to draw shapes in WinForms

      【讨论】:

      • 感谢您的回答。现在我应该在“private void pictureBox_Canvass_Paint(object sender, PaintEventArgs e){} 中放入什么以便绘制?” @Dour
      • 阅读链接的问题;您执行e.Graphics.FillRectangle(Brushes.DarkGray, rect) 之类的操作,其中rect 由您的一个按钮设置。
      • 我还有一个问题@Dour,缩放时图片框似乎滞后。有什么办法可以解决吗?
      猜你喜欢
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多