如何结合List与MouseEventArgs绘制多个图形?
实现结合List与MouseEventArgs绘制多个图形的完整方案
先说说你的现有代码已经搭好了不错的基础:Cycle类负责椭圆绘制逻辑,用List存储起点和终点来记录每个图形的绘制信息。接下来咱们一步步把功能补全,实现完整的多图形绘制效果:
1. 完善基础变量定义
首先在Form1里补充几个关键变量,保证拖动状态和临时图形的记录逻辑能跑通:
// 标记是否正在拖动绘制图形 private bool moving = false; // 临时存储当前正在绘制的图形的起点和终点 private Point Start; private Point End; // 存储所有已完成绘制的图形的起点与终点 private List<Point> star = new List<Point>(); private List<Point> endd = new List<Point>(); // 实例化Cycle类,用来执行绘制操作 private Cycle cycleDrawer = new Cycle();
2. 补全MouseMove与MouseUp事件逻辑
MouseMove要实时触发Panel重绘,显示正在拖动的临时图形;MouseUp时把完成的图形信息存入List,结束拖动状态:
private void Panel1_MouseMove(object sender, MouseEventArgs e) { if (moving) { End = e.Location; // 触发Panel重绘,实时预览拖动中的图形 Panel1.Invalidate(); } } private void Panel1_MouseUp(object sender, MouseEventArgs e) { if (moving) { moving = false; End = e.Location; // 将完成的图形的起点、终点存入List star.Add(Start); endd.Add(End); // 重绘Panel,显示所有已完成的图形 Panel1.Invalidate(); } }
3. 实现Panel的Paint事件——核心绘制逻辑
这一步是把List里存储的所有已完成图形,以及当前正在拖动的临时图形都绘制出来,还要处理起点在终点右侧/下方的情况:
private void Panel1_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; // 绘制所有已完成的椭圆 for (int i = 0; i < star.Count; i++) { Point s = star[i]; Point ePt = endd[i]; // 计算椭圆的左上角坐标、宽高(兼容拖动方向) float x = Math.Min(s.X, ePt.X); float y = Math.Min(s.Y, ePt.Y); float width = Math.Abs(ePt.X - s.X); float height = Math.Abs(ePt.Y - s.Y); // 调用Cycle类的Draw方法绘制,这里用蓝色画刷举例 cycleDrawer.Draw(g, Brushes.Blue, x, y, width, height); } // 如果正在拖动,绘制临时的椭圆(用红色画刷区分预览状态) if (moving) { float x = Math.Min(Start.X, End.X); float y = Math.Min(Start.Y, End.Y); float width = Math.Abs(End.X - Start.X); float height = Math.Abs(End.Y - Start.Y); cycleDrawer.Draw(g, Brushes.Red, x, y, width, height); } }
4. 优化Cycle类的设计(可选)
你的Cycle类现在继承Form1其实没必要,它只负责绘制逻辑,改成普通类更合理,还能避免不必要的继承关系:
public class Cycle { public void Draw(Graphics G, Brush b, float x, float y, float w, float h) { // 增加判断,避免宽高为0时的绘制异常 if (w > 0 && h > 0) { G.FillEllipse(b, x, y, w, h); } } }
5. 绑定事件到Panel(如果没在设计器绑定的话)
在Form的构造函数里把Panel的事件绑定好,确保事件能正常触发:
public Form1() { InitializeComponent(); // 绑定Panel的各类事件 Panel1.MouseDown += Panel1_MouseDown; Panel1.MouseMove += Panel1_MouseMove; Panel1.MouseUp += Panel1_MouseUp; Panel1.Paint += Panel1_Paint; }
这样一来,你就能实现完整功能:在Panel上按住鼠标拖动可绘制椭圆,拖动过程中会显示红色预览,松开鼠标后椭圆会被保存到List中,所有已绘制的蓝色椭圆都会一直保留在Panel上。
内容的提问来源于stack exchange,提问作者PreS
相关产品推荐
相关产品推荐

