简体   繁体   中英

How to draw a rectangle by holding down mouse button in a PictureBox inside a windows form?

In my application I want to draw a rectangle on a picture box by holding down a mouse button, the 2 points defining the rectangle must be retrieved from the moment the mousbutton was pressed down and when it was released. The problem is, the coordinate points of the rectangle are with respect to windows form but I need coordinate points with respect to picture box that means the picture box should use separate coordinate points and here is my code snippets...

public partial class Form1 : Form
{
    Boolean bHaveMouse;
    Point ptOriginal = new Point();
    Point ptLast = new Point();

    public Form1()
    {

        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        bHaveMouse = false;
    }
    private void MyDrawReversibleRectangle(Point p1, Point p2)
    {
        Rectangle rc = new Rectangle();

        p1 = PointToScreen(p1);
        p2 = PointToScreen(p2);
        if (p1.X < p2.X)
        {
            rc.X = p1.X;
            rc.Width = p2.X - p1.X;
        }
        else
        {
            rc.X = p2.X;
            rc.Width = p1.X - p2.X;
        }
        if (p1.Y < p2.Y)
        {
            rc.Y = p1.Y;
            rc.Height = p2.Y - p1.Y;
        }
        else
        {
            rc.Y = p2.Y;
            rc.Height = p1.Y - p2.Y;
        }
        ControlPaint.DrawReversibleFrame(rc,
                        Color.DarkGreen, FrameStyle.Thick);
        textBox2.Text = (rc.Width).ToString();
        textBox3.Text = (rc.Height).ToString();
    }



    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        Point ptCurrent = new Point(e.X, e.Y);
        if (bHaveMouse)
        {
            if (ptLast.X != -1)
            {
                MyDrawReversibleRectangle(ptOriginal, ptLast);
            }
            ptLast = ptCurrent;
            MyDrawReversibleRectangle(ptOriginal, ptCurrent);
            textBox1.Text = (ptOriginal).ToString();
            textBox4.Text = (ptLast).ToString();

        }

    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        bHaveMouse = true;
        ptOriginal.X = e.X;
        ptOriginal.Y = e.Y;
        ptLast.X = -1;
        ptLast.Y = -1;
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        bHaveMouse = false;
        if (ptLast.X != -1)
        {
            Point ptCurrent = new Point(e.X, e.Y);
            MyDrawReversibleRectangle(ptOriginal, ptLast);
        }
        ptLast.X = -1;
        ptLast.Y = -1;
        ptOriginal.X = -1;
        ptOriginal.Y = -1;
    }

I think you are overcomplicating things.

Instead of using ControlPaint you can simply get a Graphics -Object "on" your picture box, that way, inside that graphics object you have to use coordinates relative to itself and not to the control containing it, a little example:

public Form1()
{
    InitializeComponent();

    Bitmap myBitmap = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);

    using (Graphics g = Graphics.FromImage(myBitmap))
    {
        g.Clear(Color.Aqua);
        g.DrawRectangle(new Pen(Brushes.Black), 10, 10, 100, 100);
    }

    this.pictureBox1.Image = myBitmap;
}

Output of that looks like this for me (form was: 284x262 here and the picture box: 156x124 and positioned at (47, 35) relative to the form origin)

样本输出

Using most parts of your code you can use the coordinates relative to the pictue box pretty easily (I did not use the output of coordinates into a textbox and replaced your MyDrawReversibleRectangle with a simple one of mine, now you can just span a rectangle by holding down a mousebutton inside the picture box:

public partial class Form1 : Form
{
    Boolean bHaveMouse;
    Point ptOriginal = new Point();
    Point ptLast = new Point();

    public Form1()
    {
        InitializeComponent();

        this.pictureBox1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseMove);
        this.pictureBox1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseDown);
        this.pictureBox1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseUp);
    }

    private void MyDrawReversibleRectangle(Point p1, Point p2)
    {
        Bitmap myBitmap = new Bitmap(this.pictureBox1.Width, this.pictureBox1.Height);

        using (Graphics g = Graphics.FromImage(myBitmap))
        {
            g.Clear(Color.Aqua);
            g.DrawRectangle(new Pen(Brushes.Black), p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y);
        }

        this.pictureBox1.Image = myBitmap;
    }

    private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
    {
        Point ptCurrent = new Point(e.X, e.Y);
        if (bHaveMouse)
        {
            if (ptLast.X != -1)
            {
                MyDrawReversibleRectangle(ptOriginal, ptLast);
            }
            ptLast = ptCurrent;
            MyDrawReversibleRectangle(ptOriginal, ptCurrent);
        }

    }

    private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
    {
        bHaveMouse = true;
        ptOriginal.X = e.X;
        ptOriginal.Y = e.Y;
        ptLast.X = -1;
        ptLast.Y = -1;
    }

    private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
    {
        bHaveMouse = false;
        if (ptLast.X != -1)
        {
            Point ptCurrent = new Point(e.X, e.Y);
            MyDrawReversibleRectangle(ptOriginal, ptLast);
        }
        ptLast.X = -1;
        ptLast.Y = -1;
        ptOriginal.X = -1;
        ptOriginal.Y = -1;
    }
}

EDIT: You did not include that part of the code, but as I do it in the Form1 -constructor I thought I could also mention it explicitly: You need to define your mouse event handlers on the picture box or this code won't work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM