问题描述
我正在寻找使用鼠标#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;
}
}
}
}