如何在C#中使用鼠标移动和更改形状的大小

问题描述

我正在寻找使用鼠标#C移动和更改形状大小的方法。 由鼠标在名为“ captureDesign”的图片框上的位置(起点,终点)制成的形状。 我想寻求一点帮助。 我搜索了许多类似的问题案例,但仍无法解决。 如果可以的话,请让我知道。

这是我的代码。 这还不是全部,例如,我省略了使用Button_click进行形状模式选择的内容。

I studied the similar case. 但是我还没有注意到。 如何将startPt(@MouseDown)和endPt(@MouseUp)与MyMove关联以使移动成功? MyMove代码写在上部链接中。我需要改变。 实际上,我需要编写代码以更改大小,但首先,我想使用鼠标来移动它。

namespace Pilot
{
    enum DrawMode { LINE,RECTANGLE,CIRCLE,NUMBER };

    public partial class mainForm : Form
    {
        #region define
        private bool _isCaptionShow = false;
        private ScreenPicture sp;

        private IContainer components = null;

        Bitmap bitmap;


        private DrawMode drawMode;
        private Graphics g;
        private Pen pen = new Pen(Color.Red,7);
        Point startPt,endPt,currPt,prevPt,addPt;
        private int numberCount = 0;

        int rectWidth,rectHeight;
        Font font = new Font("Arial",12);

        private bool selectMode = false;

        private void selectModeButton_CheckedChanged(object sender,EventArgs e)
        {
            if (selectModeButton.Checked == true)
                selectMode = true;
            else
                selectMode = false;
        }


        MyMove m;
        Point deltaStart;
        Point deltaEnd;
        bool dragging = false;

        #region Contents on PictureBox "captureDesign;" when mouse clicked.
        private void captureDesign_MouseDown(object sender,MouseEventArgs e)
        {
            startPt = new Point(e.X,e.Y);
            prevPt = startPt;
            currPt = startPt;

            
            if (selectMode)
            {
                if (e.Button == MouseButtons.Left && m.IsPointOnLine(e.Location,5))
                {
                    dragging = true;
                    deltaStart = new Point(startPt.X- e.Location.X,startPt.Y - e.Location.Y);
                    
                }
            }
        }

        #region Contents on PictureBox captureDesign when Mouse dropped.
        private void captureDesign_MouseUp(object sender,MouseEventArgs e)
        {
            g = captureDesign.CreateGraphics();
            endPt = new Point(e.X,e.Y);

            m = new MyMove(pen,startPt,endPt);

            #region calculate between start Point ~ end Point to width,height
            if (endPt.X < startPt.X) 
            {
                rectWidth = Math.Abs(endPt.X - startPt.X);
                addPt.X = endPt.X;
            }
            else 
            {
                rectWidth = Math.Abs(endPt.X - startPt.X);
                addPt.X = startPt.X;
            }

            if (endPt.Y < startPt.Y)  
            {
                rectHeight = Math.Abs(endPt.Y - startPt.Y);
                addPt.Y = endPt.Y;
            }
            else
            {
                rectHeight = Math.Abs(endPt.Y - startPt.Y);
                addPt.Y = startPt.Y;
            }
            #endregion

            if (selectMode)  
            {
                deltaEnd = new Point(endPt.X - e.Location.X,endPt.Y - e.Location.Y); 
            }
            else  //No selectMode
            {
                #region draw the shape in case of drawMode
                switch (drawMode)
                {
                    case DrawMode.LINE:
                        if (arrowCheck.Checked == true)
                        {
                            pen.StartCap = LineCap.ArrowAnchor;
                        }
                        else
                            //g.DrawLine(pen,endPt);
                            g.DrawLine(m.mpen,m.mStart,m.mEnd);
                        break;
                    case DrawMode.RECTANGLE:
                        //g.DrawRectangle(pen,new Rectangle(startPt,new Size(endPt.X - startPt.X,endPt.Y - startPt.Y)));
                        g.DrawRectangle(pen,new Rectangle(addPt,new Size(rectWidth,rectHeight)));
                        

                        break;
                    case DrawMode.CIRCLE:
                        g.DrawEllipse(pen,rectHeight)));
                        break;

                    case DrawMode.NUMBER:
                        numberCount++;
                        g.DrawString(numberCount.ToString(),font,Brushes.White,endPt);
                        break;
                }

                #endregion
               
            }
        }

        #region 
        private void captureDesign_MouseMove(object sender,MouseEventArgs e)
        {
            if (dragging && deltaStart != null && deltaEnd != null)
            {
                m.mStart = new Point(deltaStart.X + e.Location.X,deltaStart.Y + e.Location.Y);
                m.mEnd = new Point(deltaEnd.X + e.Location.X,deltaEnd.Y + e.Location.Y);
            }
        }
}

    public class MyMove
    {
        public Pen mpen { get; set; }
        public Point mStart { get; set; }
        public Point mEnd { get; set; }

        public MyMove(Pen p,Point p1,Point p2)
        {
            mpen = p;
            mStart = p1;
            mEnd = p2;
        }

        public float slope
        {
            get
            {
                return (((float)mEnd.Y - (float)mStart.Y) / ((float)mEnd.X - (float)mStart.X));
            }
            
        }

        public float YIntercept
        {
            get
            {
                return mStart.Y - slope * mStart.X;
            }              
        }

        public bool IsPointOnLine(Point p,int cushion)
        {
            float temp = (slope * p.X + YIntercept);
            if (temp >= (p.Y-cushion) && temp <=(p.Y+cushion))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

    }


解决方法

第一个答案
一切都在MouseMove(object sender,MouseEventArgs e)上发生。
这是一个示例

private void Form1_MouseMove(object sender,MouseEventArgs e)
{
    //If we are not allowed to draw,simply return and disregard the rest of the code
    if (!_canDraw) return;

    //The x-value of our rectangle should be the minimum between the start x-value and the current x-position
    int x = Math.Min(_startX,e.X);
    //The y-value of our rectangle should also be the minimum between the start y-value and current y-value
    int y = Math.Min(_startY,e.Y);

    //The width of our rectangle should be the maximum between the start x-position and current x-position minus
    //the minimum of start x-position and current x-position
    int width = Math.Max(_startX,e.X) - Math.Min(_startX,e.X);

    //For the hight value,it's basically the same thing as above,but now with the y-values:
    int height = Math.Max(_startY,e.Y) - Math.Min(_startY,e.Y);
    _rect = new Rectangle(x,y,width,height);
    
    //Refresh the form and draw the rectangle
    Refresh();
}

protected override void OnPaint(PaintEventArgs e)
{
    //Create a new 'pen' to draw our rectangle with,give it the color red and a width of 2
    using (Pen pen = new Pen(Color.Red,2))
    {
        //Draw the rectangle on our form with the pen
        e.Graphics.DrawRectangle(pen,_rect);
    }
}

您可以在这里C# Tutorial - Drawing rectangles with the mouse进一步研究细节。

第二次回答(更新)
我实现了所需的解决方案,但使用了第三方库MoveGraphLibrary。您可以进一步阅读本文Moveable Resizable Objects

示例代码
图形对象

public class Rectangle : GraphicalObject
{
    protected RectangleF rc;
    protected Resizing resize;
    protected float wMin,wMax,hMin,hMax;
    protected int radius;
    protected int halfstrip;
    protected SolidBrush brush;

    int minsize = 25;

    // -------------------------------------------------
    public Rectangle(RectangleF rect,RectRange range,int rad,int half,Color color)
    {
        rc = new RectangleF(rect.X,rect.Y,Math.Max(minsize,rect.Width),rect.Height));
        if (range == null)
        {
            wMin = wMax = rc.Width;
            hMin = hMax = rc.Height;
        }
        else
        {
            wMin = Math.Max(minsize,Math.Min(rc.Width,range.MinWidth));
            wMax = Math.Max(rc.Width,range.MaxWidth);
            hMin = Math.Max(minsize,Math.Min(rc.Height,range.MinHeight));
            hMax = Math.Max(rc.Height,range.MaxHeight);
        }
        RectRange realrange = new RectRange(wMin,hMax);
        resize = realrange.Resizing;

        radius = rad;
        halfstrip = half;
        brush = new SolidBrush(color);
    }
    // -------------------------------------------------

    // -------------------------------------------------        RectAround
    new public RectangleF RectAround
    {
        get { return (rc); }
    }
    // -------------------------------------------------        Radius
    public int Radius
    {
        get { return (radius); }
        set
        {
            radius = Math.Abs(value);
            DefineCover();
        }
    }
    // -------------------------------------------------        HalfStrip
    public int HalfStrip
    {
        get { return (halfstrip); }
        set
        {
            halfstrip = Math.Abs(value);
            DefineCover();
        }
    }
    // -------------------------------------------------        Color
    public Color Color
    {
        get { return (brush.Color); }
        set { brush.Color = value; }
    }
    // -------------------------------------------------
    public void Draw(Graphics grfx)
    {
        grfx.FillRectangle(brush,rc);
    }
    // -------------------------------------------------        Resizing
    public Resizing Resizing
    {
        get { return (resize); }
        set
        {
            resize = value;
            DefineCover();
        }
    }
    // -------------------------------------------------        DefineCover
    public override void DefineCover()
    {
        cover = new Cover(rc,resize,radius,halfstrip);
    }
    // -------------------------------------------------
    public override void Move(int dx,int dy)
    {
        rc.X += dx;
        rc.Y += dy;
    }
    // -------------------------------------------------        MoveNode
    public override bool MoveNode(int iNode,int dx,int dy,Point ptM,MouseButtons catcher)
    {
        bool bRet = false;

        if (catcher == MouseButtons.Left)
        {
            float wNew,hNew;
            switch (resize)
            {
                case Resizing.Any:
                    if (iNode == 8)
                    {
                        Move(dx,dy);
                    }
                    else if (iNode == 0)        //LT corner
                    {
                        hNew = rc.Height - dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Top(dy);
                            bRet = true;
                        }
                        wNew = rc.Width - dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Left(dx);
                            bRet = true;
                        }
                    }
                    else if (iNode == 1)        // RT corner
                    {
                        hNew = rc.Height - dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Top(dy);
                            bRet = true;
                        }
                        wNew = rc.Width + dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Right(dx);
                            bRet = true;
                        }
                    }
                    else if (iNode == 2)        // RB corner
                    {
                        wNew = rc.Width + dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Right(dx);
                            bRet = true;
                        }
                        hNew = rc.Height + dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Bottom(dy);
                            bRet = true;
                        }
                    }
                    else if (iNode == 3)        // LB corner
                    {
                        hNew = rc.Height + dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Bottom(dy);
                            bRet = true;
                        }
                        wNew = rc.Width - dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Left(dx);
                            bRet = true;
                        }
                    }
                    else if (iNode == 4)     // on left side
                    {
                        wNew = rc.Width - dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Left(dx);
                            bRet = true;
                        }
                    }
                    else if (iNode == 5)   // on right side
                    {
                        wNew = rc.Width + dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Right(dx);
                            bRet = true;
                        }
                    }
                    else if (iNode == 6)      // on top
                    {
                        hNew = rc.Height - dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Top(dy);
                            bRet = true;
                        }
                    }
                    else if (iNode == 7)   // on bottom
                    {
                        hNew = rc.Height + dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Bottom(dy);
                            bRet = true;
                        }
                    }
                    break;

                case Resizing.NS:
                    if (iNode == 2)
                    {
                        Move(dx,dy);
                    }
                    else if (iNode == 0)      // on top
                    {
                        hNew = rc.Height - dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Top(dy);
                            bRet = true;
                        }
                    }
                    else if (iNode == 1)   // on bottom
                    {
                        hNew = rc.Height + dy;
                        if (hMin <= hNew && hNew <= hMax)
                        {
                            MoveBorder_Bottom(dy);
                            bRet = true;
                        }
                    }
                    break;

                case Resizing.WE:
                    if (iNode == 2)
                    {
                        Move(dx,dy);
                    }
                    else if (iNode == 0)     // on left side
                    {

                        wNew = rc.Width - dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Left(dx);
                            bRet = true;
                        }
                    }
                    else if (iNode == 1)   // on right side
                    {
                        wNew = rc.Width + dx;
                        if (wMin <= wNew && wNew <= wMax)
                        {
                            MoveBorder_Right(dx);
                            bRet = true;
                        }
                    }
                    break;

                case Resizing.None:
                    Move(dx,dy);
                    break;
            }
        }
        return (bRet);
    }
    // -------------------------------------------------        MoveBorder_Top
    private void MoveBorder_Top(int dy)
    {
        rc.Y += dy;
        rc.Height -= dy;
    }
    // -------------------------------------------------        MoveBorder_Bottom
    private void MoveBorder_Bottom(int dy)
    {
        rc.Height += dy;
    }
    // -------------------------------------------------        MoveBorder_Left
    private void MoveBorder_Left(int dx)
    {
        rc.X += dx;
        rc.Width -= dx;
    }
    // -------------------------------------------------        MoveBorder_Right
    private void MoveBorder_Right(int dx)
    {
        rc.Width += dx;
    }

    public PointF Location
    {
        get
        {
            return rc.Location;
        }
    }
}

主表格

public partial class Form1 : Form
{
    RectRange rr;

    // Variables use for Moving & Resizing
    NumericUpDown numericUD_Radius = new NumericUpDown();
    NumericUpDown numericUD_HalfStrip = new NumericUpDown();
    string[] strs = new string[] {"Circles' radius","Half strip width"
                                   };
    Mover mover;
    Point ptMouse_Down;
    bool bShowCovers = false;
    RigidlyBoundRectangles rigidrectsView;
    List<Shapes.Rectangle> rects = new List<Shapes.Rectangle>();
    int radius,halfstrip;

    // Variables use for Drawing
    bool isMouseDown = false;

    public Form1()
    {
        InitializeComponent();

        lblXAxis.Text = $"X Axis: -";
        lblYAxis.Text = $"Y Axis: -";

        numericUD_Radius.Value = 6;
        numericUD_HalfStrip.Value = 3;

        mover = new Mover(panel1);

        SizeF[] sizefStrs = Auxi_Geometry.MeasureStrings(this,strs);
        rigidrectsView = new RigidlyBoundRectangles(new Control[] { numericUD_Radius,numericUD_HalfStrip });
        rigidrectsView.Add(Auxi_Geometry.RectangleToRectangleSide(numericUD_Radius.Bounds,Side.E,sizefStrs[0],4),"Radius");
        rigidrectsView.Add(Auxi_Geometry.RectangleToRectangleSide(numericUD_HalfStrip.Bounds,sizefStrs[1],"Strip");
        rigidrectsView.AddUnionRectangle();

        radius = Convert.ToInt32(numericUD_Radius.Value);
        halfstrip = Convert.ToInt32(numericUD_HalfStrip.Value);

        rr = new RectRange(panel1.MinimumSize.Width,panel1.Size.Width,panel1.MinimumSize.Height,panel1.Size.Height);

        rects.Add(new Shapes.Rectangle(new RectangleF(100,100,300,400),rr,halfstrip,Color.Black));

        RenewMover();
    }

    private void RenewMover()
    {
        mover.Clear();
        mover.Insert(0,rigidrectsView);

        for (int i = 0; i < rects.Count; i++)
        {
            mover.Add(rects[i]);
        }
    }

    private void panel1_Paint(object sender,PaintEventArgs e)
    {
        Graphics grfx = e.Graphics;

        GraphicalObject grobj;
        for (int i = mover.Count - 1; i >= 0; i--)
        {
            grobj = mover[i].Source;
            if (grobj is Shapes.Rectangle)
            {
                (grobj as Shapes.Rectangle).Draw(grfx);
            }

            if (bShowCovers)
            {
                mover[i].DrawCover(grfx);
            }
        }
    }

    private void panel1_MouseMove(object sender,MouseEventArgs e)
    {
        lblXAxis.Text = $"X Axis: {e.X}";
        lblYAxis.Text = $"Y Axis: {e.Y}";

        if (rbMoveOrResize.Checked && mover.Move(e.Location))
        {
            panel1.Invalidate();
        }
        else
        {
            if (isMouseDown)
            {
                var rectangle = rects.Last();
                var drawRectangle = new Shapes.Rectangle(new RectangleF(rectangle.Location.X,rectangle.Location.Y,e.X - rectangle.Location.X,e.Y - rectangle.Location.Y),Color.Black);

                rects.Remove(rects.Last());
                rects.Add(drawRectangle);

                RenewMover();
                panel1.Invalidate();
            }
        }
    }

    private void panel1_MouseLeave(object sender,EventArgs e)
    {
        lblXAxis.Text = $"X Axis: -";
        lblYAxis.Text = $"Y Axis: -";
    }

    private void panel1_MouseDown(object sender,MouseEventArgs e)
    {
        if (rbMoveOrResize.Checked)
        {
            ptMouse_Down = e.Location;
            mover.Catch(e.Location,e.Button);
        }
        else
        {
            isMouseDown = true;

            rects.Add(new Shapes.Rectangle(new RectangleF(e.Location.X,e.Location.Y,0),Color.Black));
        }
    }

    private void panel1_MouseUp(object sender,MouseEventArgs e)
    {
        if (rbMoveOrResize.Checked && mover.Release())
        {
            if (e.Button == MouseButtons.Left &&
                Auxi_Geometry.Distance(ptMouse_Down,e.Location) <= 3)
            {
                GraphicalObject grobj = mover[mover.ReleasedObject].Source;
                if (grobj is Shapes.Rectangle)
                {
                    PopupRectangle(grobj.ID);
                }
            }
        }
        else
        {
            isMouseDown = false;
        }
    }

    private void rb_CheckedChanged(object sender,EventArgs e)
    {
        bShowCovers = rbMoveOrResize.Checked;
        panel1.Invalidate();
    }

    private void PopupRectangle(long id)
    {
        for (int i = rects.Count - 1; i > 0; i--)
        {
            if (id == rects[i].ID)
            {
                Shapes.Rectangle elem = rects[i];
                rects.RemoveAt(i);
                rects.Insert(0,elem);
                RenewMover();
                panel1.Invalidate();
                break;
            }
        }
    }
}

样品输出
SAMPLE OUTPUT

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...