DrawEllipse 和 FillEllipse 是 C# GDI+ 中绘制圆形的唯二正解,因系统无 DrawCircle 方法,圆本质是宽高相等的椭圆,需传入 Width == Height 的 Rectangle;前者画空心边框,后者填充实心,参数一致但用途不可混用。

直接说结论:DrawEllipse 和 FillEllipse 就是 C# GDI+ 里画圆的唯二正解,没有 DrawCircle 这种方法,强行找会白费时间。
为什么用 DrawEllipse 而不是 DrawCircle
GDI+ 没有独立的圆形绘制 API,所有“圆”本质上都是宽高相等的椭圆。系统只提供 DrawEllipse 和 FillEllipse,它们的参数类型全是 Rectangle —— 这意味着你传进去的矩形必须满足 rect.Width == rect.Height,否则画出来就是椭圆。
- 传入
new Rectangle(10, 10, 50, 50)→ 正圆,直径 50 - 传入
new Rectangle(10, 10, 50, 30)→ 压扁的椭圆,不是圆 - 想画圆心在 (100, 100)、半径为 20 的圆?得算出左上角坐标:
new Rectangle(80, 80, 40, 40)
DrawEllipse 和 FillEllipse 的关键区别
前者只画边框(空心),后者填充内部(实心),两者参数完全一致,不能混用意图。
- 边框颜色由
Pen决定,例如new Pen(Color.Red, 2) - 填充颜色由
Brush决定,常用SolidBrush或LinearGradientBrush - 如果只调用
DrawEllipse却没调用FillEllipse,圆看起来就是“透明”的——其实只是没填色 - 性能上,
FillEllipse开销略高,尤其在大量小圆重绘时要注意帧率
鼠标跟随动态画圆(比如眼珠)的坑点
这类效果依赖频繁重绘,容易出现残影或闪烁,核心在于:每次重绘前必须清掉旧位置。
- 不能只画新圆,必须先用背景色
FillEllipse盖掉上一帧的旧圆 - 推荐在
OnPaint中统一绘制,而不是在MouseMove里直接调Graphics—— 否则可能触发无效区域外的绘制 - 计算圆心偏移时,别直接用鼠标坐标减去控件原点;要减去圆心相对于控件左上角的基准偏移量,否则拖动时会跳变
- 如果圆需要响应点击,判断逻辑得基于
Point到圆心距离 ≤ 半径,而不是用Rectangle.Contains()(那是矩形判定)
真正麻烦的从来不是“怎么画”,而是“什么时候清、清哪里、清多少”。GDI+ 的圆没有抗锯齿开关、不自动缓存、不区分 DPI 缩放 —— 这些细节全得自己兜底。










