Rad Studio下用C++绘制TDBGrid标题下划线无效的原因排查
1. 绘制顺序被默认绘制逻辑直接覆盖
TDBGrid的事件触发逻辑和直觉上的顺序完全不同:OnDrawColumnCell是在控件默认绘制流程执行之前触发的。只要你没有把控件的DefaultDrawing属性设为false,你的自绘代码跑完之后,控件会立刻执行默认的单元格绘制——包括用系统默认背景色填满整个单元格、绘制默认边框和标题文字,所有你在事件里画的内容都会被这层默认填充完全盖在下面,根本不会露出来。
2. 绘制坐标刚好落在GDI裁剪范围外
OnDrawColumnCell里拿到的Canvas,默认裁剪区域和事件传入的Rect参数完全一致,但GDI的矩形绘制遵循半开区间规则:当前单元格允许绘制的Y坐标范围是Rect.Top 到 Rect.Bottom - 1。
你代码里把分隔线的Y值设为Rect.Bottom,这个位置刚好在当前单元格的可绘制边界外,会被GDI的自动裁剪机制直接删掉,不会渲染任何内容。哪怕其他配置全对,这1个像素的偏移就会导致线条完全消失。
3. 未判断当前绘制的是否为标题固定行
OnDrawColumnCell会触发所有单元格的绘制流程,包括所有普通数据行和固定的标题行。如果你没有通过事件参数的State判断当前目标:
- 绘制逻辑可能跑到了普通数据行上,根本没在标题行位置执行
- 没有在标题行分支完成基础的背景绘制,直接画的线会和透明背景融合,看不见效果
判断标识很简单:只要State里包含gdFixed标记,就代表当前正在绘制固定的标题行区域。
4. 自定义线条和控件自带边框完全重叠
如果TDBGrid的Options里默认开启了dgRowLines(自带行分隔线),你在单元格底部画的黑色线条会和系统自带的行边框完全重叠:要么被系统边框的绘制逻辑覆盖,要么因为颜色、宽度和自带边框完全一致,视觉上根本看不出你自定义的分隔线。
要是GridLineWidth设为0,你在单元格边界位置找坐标画的线,只要差1个像素就会完全找不到渲染位置。
可行的修正思路
要实现预期的标题下分隔线效果,核心调整包括:
- 把网格的
DefaultDrawing设为false,切断默认逻辑对自绘内容的覆盖;在事件里先手动调用DefaultDrawCell,把标题文字、单元格背景画好之后,再执行自定义画线的逻辑 - 把分隔线的Y坐标从
Rect.Bottom调整为Rect.Bottom - 1,确保坐标落在GDI允许的可绘制范围内 - 先判断
State是否包含gdFixed,确认当前绘制的是标题行再执行画线,避免给普通数据行重复添加分隔线 - 匹配标题行的实际背景色调整画笔颜色,保证线条和背景有足够的对比度
内容的提问来源于stack exchange,提问作者KapitaiN

