C#使用Panel、Graphics和Point绘制多点连线仅单条显示的问题排查
错误原因
你的问题出在DisplayShape方法的两处逻辑错误:
- 前序点赋值位置错误:
prevPoint = pt代码被放在了if (prevPoint != null)判断块的内部。第一次遍历第一个点时prevPoint为null,不会进入判断块,也就永远不会给prevPoint赋值,后续所有遍历的prevPoint都保持为null,自然不会绘制相邻点之间的连线。你看到的单条线实际上是循环中反复绘制的首尾点连线。 - 首尾闭合线绘制位置错误:首尾点连线的代码被放在了foreach循环内部,会重复执行多次,实际上只需要所有相邻点连线绘制完成后执行一次即可。
修复后的代码
修改后的DisplayShape方法如下:
void DisplayShape(List<Point> Shp,Pen pen, Graphics G) { if (Shp.Count < 2) return; // 点数不足时直接返回避免报错 Point? prevPoint = null; foreach(Point pt in Shp) { // 绘制点标记 G.DrawEllipse(pen, new Rectangle(pt.X - 2, pt.Y - 2, 4, 4)); // 前序点存在时绘制两点连线 if (prevPoint != null) { G.DrawLine(pen, (Point)prevPoint, pt); } // 不管前序点是否存在,都更新前序点为当前点 prevPoint = pt; } // 首尾闭合线放在循环外,仅绘制一次 G.DrawLine(pen, Shp[0], Shp[Shp.Count - 1]); }
额外优化建议
- 不要用
panel1.CreateGraphics()获取绘图对象,这种方式绘制的图形在窗口被遮挡、拖动、缩放后会消失。正确做法是给panel1的Paint事件添加处理方法,把绘图逻辑写在Paint事件中,通过e.Graphics绘图,点击按钮时只需要调用panel1.Invalidate()触发重绘即可。 - Pen属于GDI资源,使用完需要主动释放,建议用
using块包裹Pen的创建逻辑,避免资源泄漏。
内容的提问来源于stack exchange,提问作者user16612111
相关产品推荐
相关产品推荐

