Graphics.DrawRectangle画不出框是因为Graphics对象来源非法,必须从控件、位图或Paint事件获取;Pen/Brush需及时释放或复用;坐标需考虑客户区与DPI缩放;DrawString模糊应设置TextRenderingHint。
Graphics.DrawRectangle 画不出框?检查 Graphics 对象来源
直接 new graphics 是非法的,它不能凭空创建。必须从控件(如 picturebox、panel)、位图(bitmap)或窗体的 paint 事件中获取——否则会抛出 object is null 或静默失败。
- 在窗体上绘图,优先用
Paint事件:参数e.Graphics是唯一安全可用的实例 - 想离屏绘制(比如生成图片),先 new
Bitmap,再调用bitmap.CreateGraphics()——但注意:这仍不推荐;应改用Graphics.FromImage(bitmap) -
CreateGraphics()返回的Graphics会在窗体重绘时被清空,不适合持久绘图
Pen 和 Brush 没生效?别漏掉 Dispose 或复用陷阱
Pen/Brush 是 GDI+ 的非托管资源,不及时释放会导致内存缓慢泄漏,尤其在循环绘图中特别明显;同时,反复 new 同样参数的 Pen(比如颜色、宽度相同)也会浪费资源。
- 用完立刻
pen.Dispose(),或包进using (var pen = new Pen(...)) { ... } - 全局复用常用笔刷:定义
static readonly Pen BlackPen = new Pen(Color.Black, 1);,但注意线宽、颜色等不可变,换参数就得新建 - 不要对同一个
Pen实例反复设置Width或Color——这些属性是只读的,赋值无效
坐标画歪了?搞清客户区、设备坐标和 DPI 缩放
你写的 DrawRectangle(g, 10, 10, 100, 50) 看起来偏右下?大概率是没考虑控件的 ClientRectangle 边界,或系统启用了高 DPI 缩放。
- 绘图前先确认目标区域:比如在
PictureBox中,应基于pictureBox.ClientSize计算位置,而不是硬写像素值 - 启用 DPI 感知后,
Graphics.DpiX可能不是 96,直接按设计尺寸画会缩放失真;用Graphics.ScaleTransform()校正,或改用Graphics.Transform配合Matrix - 避免在
Resize事件里直接绘图——重绘应统一走Invalidate()+Paint,否则易出现撕裂或闪烁
为什么 DrawString 文字模糊?字体渲染模式很关键
默认 TextRenderingHint.SystemDefault 在非整数缩放或 ClearType 关闭时,文字边缘发虚,尤其小字号下明显。
- 显式设置抗锯齿:在
Paint事件开头加g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit; - 避免用
Font构造函数传入浮点大小(如new Font("Arial", 9.75f)),强制取整或用Graphics.MeasureString前先确认字体是否支持该尺寸 - 如果目标是图标内嵌文字,优先考虑
GraphicsPath+FillPath,比DrawString更可控、更锐利
GDI+ 绘图真正难的不是 API 调用,而是每次绘图前得想清楚:这个 Graphics 从哪来、生命周期归谁管、坐标系以谁为原点、缩放有没有偷偷改过它。漏掉其中一环,图形就可能不出现、错位、模糊或吃内存。










