简体   繁体   English

如何通过在Windows窗体内的PictureBox中按住鼠标按钮来绘制矩形?

[英]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. 在我的应用程序中,我想通过按住鼠标按钮在图片框上绘制一个矩形,从按下mousbutton的那一刻起以及释放它的那一刻起,必须检索定义该矩形的2个点。 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... 问题是,矩形的坐标点是相对于Windows窗体的,但我需要相对于图片框的坐标点,这意味着图片框应使用单独的坐标点,这是我的代码段...

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: 不用使用ControlPaint您可以简单地在您的图片框上获得一个Graphics -Object,那样,在该图形对象内,您必须使用相对于其自身的坐标,而不是相对于包含它的控件,这是一个小例子:

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) 对我来说,它的输出看起来像这样(表单是:284x262,图片框:156x124,相对于表单原点位于(47,35))

样本输出

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: 使用代码的大部分内容,您可以轻松地使用相对于pictue框的坐标(我没有将坐标的输出使用到文本框中, MyDrawReversibleRectangle用我的简单的一个替换了MyDrawReversibleRectangle ,现在您可以通过按住在图片框内按下鼠标按钮:

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. 编辑:您没有包括代码的那部分,但是正如我在Form1 -constructor中所做的那样,我想我也可以明确提及它:您需要在图片框上定义mouse event handlers ,否则此代码将无法工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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