Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

c# - How to remove all the drawn rectangles on the picture box? (Not on the image)

I have tried using the following code:

        pictureBox1.Invalidate(); 
        //or
        pictureBox1.Update();
        //or
        Refresh();

But it just did nothing on it. I want to clear all the drawn graphics on my picture box as after I click the next page I want to draw the new rectangles on it. So, please don't provide me such a solution:

g.FillRectangle(Brushes.Black, new Rectangle(0, 0, pictureBox1.Width, pictureBox1.Height))

or

Graphics.Clear();

Anyone want to share the solution with me? I am appreciated with it.

page 2 page 3

Form2.cs

    private void pictureBox1_Paint(object sender, PaintEventArgs e)
    {
        Pen pen = new Pen(Color.Red, 2);
        e.Graphics.DrawRectangle(pen, rect);     
    }


    bool draw;
    int x_start, y_start;
    Rectangle rect;
    //UserRect rect;
    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {

        }
        else if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {
            pictureBox1.Cursor = Cursors.Cross;
            draw = true;
            x_start = e.X;
            y_start = e.Y;
        }
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {


        }else if(e.Button == MouseButtons.Right)
        {
            pictureBox1.Cursor = Cursors.Cross;

        }

        if (!draw) return;
        LocalMousePosition = pictureBox1.PointToClient(Cursor.Position);

        int x = Math.Min(x_start, LocalMousePosition.X);
        int y = Math.Min(y_start, LocalMousePosition.Y);

        int width = Math.Max(x_start, LocalMousePosition.X) - Math.Min(x_start, LocalMousePosition.X);
        int height = Math.Max(y_start, LocalMousePosition.Y) - Math.Min(y_start, LocalMousePosition.Y);

        rect = new Rectangle(x, y, width, height);

        xx = x;
        yy = y;
        ww = width;
        hh = height;

        Refresh();
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {


        if (e.Button == System.Windows.Forms.MouseButtons.Right)
        {

            //pictureBox1.Cursor = Cursors.Default;
            draw = false;

            rectang = new UserRect(rect);
            rect = new Rectangle(e.X, e.Y, 0, 0);

            rectang.SetPictureBox(this.pictureBox1);   
        }
        else if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {
        pictureBox1.Cursor = Cursors.Default;
        _tracking = false;

        }


    }

UserRect.cs

public void Draw(Graphics g)
    {
        g.DrawRectangle(new Pen(Color.Green), rect);

        foreach (PosSizableRect pos in Enum.GetValues(typeof(PosSizableRect)))
        {
            g.DrawRectangle(new Pen(Color.Red), GetRect(pos));
        }


    }

        public void SetPictureBox(PictureBox p)
    {
        this.mPictureBox = p;
        mPictureBox.MouseDown += new MouseEventHandler(mPictureBox_MouseDown);
        mPictureBox.MouseUp += new MouseEventHandler(mPictureBox_MouseUp);
        mPictureBox.MouseMove += new MouseEventHandler(mPictureBox_MouseMove);
        mPictureBox.Paint += new PaintEventHandler(mPictureBox_Paint);
    }

    private void mPictureBox_Paint(object sender, PaintEventArgs e)
    {

        try
        {
            Draw(e.Graphics);
        }
        catch (Exception exp)
        {
            System.Console.WriteLine(exp.Message);
        }

    }

    private void mPictureBox_MouseDown(object sender, MouseEventArgs e)
    {
        mIsClick = true;

        nodeSelected = PosSizableRect.None;
        nodeSelected = GetNodeSelectable(e.Location);

        if (rect.Contains(new Point(e.X, e.Y)))
        {
            mMove = true;
        }
        oldX = e.X;
        oldY = e.Y;
    }

    private void mPictureBox_MouseUp(object sender, MouseEventArgs e)
    {
        //MessageBox.Show(rect.ToString());
        mIsClick = false;
        mMove = false;


    }

     private void mPictureBox_MouseMove(object sender, MouseEventArgs e)
    {
        ChangeCursor(e.Location);
        if (mIsClick == false)
        {
            return;
        }

        Rectangle backupRect = rect;

        if (e.Button == System.Windows.Forms.MouseButtons.Left)
        {

            switch (nodeSelected)
            {
                case PosSizableRect.LeftUp:
                    rect.X += e.X - oldX;
                    rect.Width -= e.X - oldX;
                    rect.Y += e.Y - oldY;
                    rect.Height -= e.Y - oldY;
                    break;
                case PosSizableRect.LeftMiddle:
                    rect.X += e.X - oldX;
                    rect.Width -= e.X - oldX;
                    break;
                case PosSizableRect.LeftBottom:
                    rect.Width -= e.X - oldX;
                    rect.X += e.X - oldX;
                    rect.Height += e.Y - oldY;
                    break;
                case PosSizableRect.BottomMiddle:
                    rect.Height += e.Y - oldY;
                    break;
                case PosSizableRect.RightUp:
                    rect.Width += e.X - oldX;
                    rect.Y += e.Y - oldY;
                    rect.Height -= e.Y - oldY;
                    break;
                case PosSizableRect.RightBottom:
                    rect.Width += e.X - oldX;
                    rect.Height += e.Y - oldY;
                    break;
                case PosSizableRect.RightMiddle:
                    rect.Width += e.X - oldX;
                    break;

                case PosSizableRect.UpMiddle:
                    rect.Y += e.Y - oldY;
                    rect.Height -= e.Y - oldY;
                    break;

                default:
                    if (mMove)
                    {
                        rect.X = rect.X + e.X - oldX;
                        rect.Y = rect.Y + e.Y - oldY;
                    }
                    break;
        }
    }
        oldX = e.X;
        oldY = e.Y;

        if (rect.Width < 5 || rect.Height < 5)
        {
            rect = backupRect;
        }

        TestIfRectInsideArea();

        mPictureBox.Invalidate();
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Generally, I would split drawing graphics between _Paint event as you have it (for interactive drawing, such as selection box and mouse-move related stuff) and separate underlaying image.

There are several reasons for that, such as control over what you want to draw (imagine you want to draw only retangle 1, 3 and 5, if a some checkbox is not checked and then draw all of 1 to 6 if it is checked) and performance (with large amount of data). You can do all of that in _Paint, but it will bloat. In contrast to that, you can split draw task into several functions, which is very handy for large drawing.

Very simplified example - VB.NET:

Dim UnderlayingImage as Image
UnderLayingImage = New Bitmap(Me.PictureBox1.Width, Me.Picturebox1.Height)

Dim g As Graphics = Graphics.FromImage(UnderLayingImage)
Dim bgBrush As SolidBrush = New SolidBrush(Color.LightSlateGray)
Dim bgBrushWhite As SolidBrush = New SolidBrush(Color.White)
Dim shPen As Pen = New Pen(Color.Black)

Dim rect As RectangleF = New RectangleF(50, 50, 100, 100)
g.FillRectangle(bgBrush, rect)
g.DrawRectangle(Pens.Black, Rectangle.Round(rect))

Me.PictureBoxDrawing.Image = UnderLayingImage 

Translated to C#:

Image UnderlayingImage;
UnderLayingImage = new Bitmap(this.PictureBox1.Width, this.Picturebox1.Height);

Graphics g = Graphics.FromImage(UnderLayingImage);
SolidBrush bgBrush = new SolidBrush(Color.LightSlateGray);
SolidBrush bgBrushWhite = new SolidBrush(Color.White);
Pen shPen = new Pen(Color.Black);

RectangleF rect = new RectangleF(50, 50, 100, 100);
g.FillRectangle(bgBrush, rect);
g.DrawRectangle(Pens.Black, Rectangle.Round(rect));

this.PictureBoxDrawing.Image = UnderLayingImage;

And back to your question: This way you don't Clear your drawing, but you redraw it and in the process you decide what to include and what to ommit.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...