Deleting drawn rectangle zoom box after zooming in

你离开我真会死。 提交于 2019-12-12 05:27:28

问题


I'm trying to code a draggable rectangle zoombox that's transparent, once the mouse is up again, it zooms into that area and deletes the drawn rectangle.

I've got the zoom working and drawing the rectangle, however I can't 1) Figure out how to make it transparent, and 2) Figure out how to delete the rectangle after it's zoomed in. It gets deleted again once the mouse is clicked down to draw another zoombox on the zoomed in image (I'm drawing a fractal) but I can't figure out what to write to get it to delete after zooming in.

Paint

private void Form1_Paint(object sender, PaintEventArgs e)
        {                
            Graphics windowG = e.Graphics;
            windowG.DrawImageUnscaled(picture, 0, 0);
            if (rectangle == true)
            {
               e.Graphics.FillRectangle(Brushes.Aquamarine, rec);
            }
            if (rectangle == false)
            {
                Invalidate();
            }


        }

Mouse Down

                rectangle = true;
                if (e.Button == MouseButtons.Left)
                {
                    rec = new Rectangle(e.X, e.Y, 0, 0);
                    Invalidate();
                }

Mouse up

{
    rectangle = false;
}

Mouse Move

if (e.Button == MouseButtons.Left)
                {
                    rec.Width = e.X - rec.X;
                    rec.Height = e.Y - rec.Y;
                    Invalidate();
                }

回答1:


At first I thought you need this:

  1. This is one of the very rare cases where your drawing should not be done in the Paint event but in the MouseMove using a Graphics object created with CreateGraphics.

The reason why this is the right way here is that for this kind of interactive rubberband drawing you do not want the drawing to persist. Other examples would be a line preview or a cursor cross.

  1. To make the Rectangle transparent you can either

    • Use DrawRectangle
    • or use a semi-transparent color and FillRectangle
    • or use both as in the example below:

Here is the code you need:

Point mDown = Point.Empty;

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    mDown = e.Location;  // note the first corner
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    Invalidate();   // clear the rectangle
}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (e.Button == System.Windows.Forms.MouseButtons.Left)
    using (Graphics G = this.CreateGraphics() ) // !!! usually wrong !!!
    {
        G.Clear(BackColor); // Invalidate();
        Rectangle rect = rectangle(mDown, e.Location);
        // either
        using (SolidBrush brush = new SolidBrush(Color.FromArgb(32, 255, 0, 0)))
            G.FillRectangle(brush, rect);
        // or
        G.DrawRectangle(Pens.Red, rect);
    }
}

This is a function that lets you start drawing any any corner, not just top left:

Rectangle rectangle (Point p1, Point p2)
{
    int x = Math.Min(p1.X, p2.X);
    int y = Math.Min(p1.Y, p2.Y);
    int w = Math.Abs(p1.X - p2.X);
    int h = Math.Abs(p1.Y - p2.Y);
    return new Rectangle(x, y, w, h);
}

Note that if you have a BackgroundImage this above code won't work so well.

But now I think this is closer to your situation:

In this case we go back to the normal way and draw things in the Paint but only as long as the mouse button is pressed. As we don't have the mouse parameters here we need another class level Point and also use the Control.MouseButtons property:

Point mCurrent = Point.Empty;

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    mCurrent = e.Location;
    Invalidate();
}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    mDown = Point.Empty;
    mCurrent = Point.Empty;
    Invalidate();
}

private void Form1_Paint(object sender, PaintEventArgs e)
{
    if (Control.MouseButtons == System.Windows.Forms.MouseButtons.Left)
    {
        Rectangle rect = rectangle(mDown, mCurrent);
        // either one..
        using (SolidBrush brush = new SolidBrush(Color.FromArgb(32, 255, 0, 0)))
            e.Graphics.FillRectangle(brush, rect);
        // ..or both of these
        e.Graphics.DrawRectangle(Pens.Red, rect);
    }

}

So to sum it up: Besides quite a few details your main problem is missing the check for the mouse button in the paint event..



来源:https://stackoverflow.com/questions/33568377/deleting-drawn-rectangle-zoom-box-after-zooming-in

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!