如何在C#中拖动和移动形状
在C#WindoeFormsApplication中,是否可以选择,因此可以使用鼠标移动或删除绘制的形状? 喜欢windows paint程序。
形状绘图完全正常,所有点都存储在一些数组中。 如此线描示例
Point Latest { get; set; } List _points = new List(); protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); // Save the mouse coordinates Latest = new Point(eX, eY); // Force to invalidate the form client area and immediately redraw itself. Refresh(); } protected override void OnPaint(PaintEventArgs e) { var g = e.Graphics; base.OnPaint(e); if (_points.Count > 0) { var pen = new Pen(Color.Navy); var pt = _points[0]; for(var i=1; _points.Count > i; i++) { var next = _points[i]; g.DrawLine(pen, pt, next); pt = next; } g.DrawLine(pen, pt, Latest); } } private void Form1_MouseClick(object sender, MouseEventArgs e) { Latest = new Point(eX, eY); _points.Add(Latest); Refresh(); }
我可以让它通过基本线性代数计算鼠标位置和每条线之间的最短距离,并设置一个阈值距离,如果它短于阈值,则选择该线,并可以通过鼠标拖动或编辑。 但是,只是想知道,有没有什么方法可以更容易管理这样的任务? 主要是选择部分。 任何建议将不胜感激,谢谢!
要命中测试形状,您不需要线性代数。 您可以为形状创建GraphicsPath
,然后使用GraphicsPath.IsVisible
方法或GraphicsPath.IsOutlineVisible
方法执行命中测试。
例
例如,您可以创建一个基本IShape
接口,其中包含命中测试,绘图和移动的方法。 然后在类中实现这些方法。 您还可以创建一个DrawingSurface
控件,它可以处理命中测试,绘制和移动IShape
对象。
在下面的示例中,我们创建了IShape
接口, Line
和Circle
类。 我们还创建了一个DrawingSurface
控件。 为了测试这个例子,它足以将一个DrawingSurface
控件放在Form
并处理Form
Load
事件并添加一些形状,然后运行应用程序并尝试移动形状。
IShape的
该接口包含一些有用的方法,如果任何类实现它们,可以用于绘图,命中测试和移动。 在本示例的最后,您可以看到一个可以简单地使用IShape
实现的DrawingSurface
控件:
public interface IShape { GraphicsPath GetPath(); bool HitTest(Point p); void Draw(Graphics g); void Move(Point d); }
线
这是一个实现IShape
接口的行类。 如果点击线路进行点击测试,则HitTest
返回true。 另外为了让你更简单地选择线路,我为命中测试增加了2分:
public class Line : IShape { public Line() { LineWidth = 2; LineColor = Color.Black; } public int LineWidth { get; set; } public Color LineColor { get; set; } public Point Point1 { get; set; } public Point Point2 { get; set; } public GraphicsPath GetPath() { var path = new GraphicsPath(); path.AddLine(Point1, Point2); return path; } public bool HitTest(Point p) { var result = false; using (var path = GetPath()) using (var pen = new Pen(LineColor, LineWidth + 2)) result = path.IsOutlineVisible(p, pen); return result; } public void Draw(Graphics g) { using (var path = GetPath()) using (var pen = new Pen(LineColor, LineWidth)) g.DrawPath(pen, path); } public void Move(Point d) { Point1 = new Point(Point1.X + dX, Point1.Y + dY); Point2 = new Point(Point2.X + dX, Point2.Y + dY); } }
圈
这是一个实现IShape
接口的圆类。 如果点击圈子进行点击测试,则HitTest
返回true:
public class Circle : IShape { public Circle() { FillColor = Color.Black; } public Color FillColor { get; set; } public Point Center { get; set; } public int Radious { get; set; } public GraphicsPath GetPath() { var path = new GraphicsPath(); var p = Center; p.Offset(-Radious, -Radious); path.AddEllipse(pX, pY, 2 * Radious, 2 * Radious); return path; } public bool HitTest(Point p) { var result = false; using (var path = GetPath()) result = path.IsVisible(p); return result; } public void Draw(Graphics g) { using (var path = GetPath()) using (var brush = new SolidBrush(FillColor)) g.FillPath(brush, path); } public void Move(Point d) { Center = new Point(Center.X + dX, Center.Y + dY); } }
DrawingSurface
控件,绘制一个形状列表。 它还在MouseDown
执行命中测试,并在拖动时移动形状。 您应该向控件添加一些形状,如Line
或Circle
to Shapes
集合。
上述就是C#学习教程:如何在C#中拖动和移动形状分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
public class DrawingSurface : Control { public List Shapes { get; private set; } IShape selectedShape; bool moving; Point previousPoint = Point.Empty; public DrawingSurface() { DoubleBuffered = true; Shapes = new List (); } protected override void OnMouseDown(MouseEventArgs e) { for (var i = Shapes.Count - 1; i >= 0; i--) if (Shapes[i].HitTest(e.Location)) { selectedShape = Shapes[i]; break; } if (selectedShape != null) { moving = true; previousPoint = e.Location; } base.OnMouseDown(e); } protected override void OnMouseMove(MouseEventArgs e) { if (moving) { var d = new Point(eX - previousPoint.X, eY - previousPoint.Y); selectedShape.Move(d); previousPoint = e.Location; this.Invalidate(); } base.OnMouseMove(e); } protected override void OnMouseUp(MouseEventArgs e) { if (moving) { selectedShape = null; moving = false; } base.OnMouseUp(e); } protected override void OnPaint(PaintEventArgs e) { e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; foreach (var shape in Shapes) shape.Draw(e.Graphics); } }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1011234.html