TStringGrid列背景渲染异常:按第9列颜色设置前4列背景失效
问题分析与修复方案
核心问题所在
你的代码里有个致命错误:获取颜色时用了TStringGrid(Sender).Row,这个属性拿的是当前选中的行,不是你正在绘制的那一行(也就是方法参数里的Row)。这就导致所有要画的行都套用了选中行的颜色,直接引发了你遇到的所有异常。
修正后的完整代码
procedure TDataGrid.OnDrawColumnBackground(Sender: TObject; const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF; const Row: Integer; const Value: TValue; const State: TGridDrawStates); var RowColor : TBrush; ColorStr: string; begin if Column.Index < 4 then begin // 注意:TStringGrid列索引从0开始,第9列对应索引8 ColorStr := TStringGrid(Sender).Cells[8, Row]; RowColor := TBrush.Create(TBrushKind.Solid, TAlphaColors.Alpha); try RowColor.Color := System.UIConsts.StringToAlphaColor(ColorStr); Canvas.FillRect(Bounds, 0, 0, [], 1, RowColor); // 关闭默认绘制,防止系统默认背景覆盖我们的设置 TStringGrid(Sender).DefaultDrawing := False; finally // 用完画笔一定要释放,避免内存泄漏 RowColor.Free; end; end; end;
额外优化点
- 列索引修正:之前用
9是错的,因为TStringGrid的列从0开始计数,第9列实际是索引8,这个必须改,不然拿的是第10列的颜色值。 - 内存泄漏修复:手动创建的TBrush要记得释放,用
try-finally块保证不管有没有异常都会释放资源。 - DefaultDrawing设置:改成
False,不然系统默认的绘制逻辑会覆盖你自定义的背景色,白忙活。 - 可选:颜色有效性校验:如果第9列的颜色字符串可能写错(比如拼错颜色名),可以加个判断兜底:
if not TAlphaColorHelper.TryParse(ColorStr, RowColor.Color) then RowColor.Color := TAlphaColors.White; // 给个默认颜色,比如白色
为什么之前会出现那些异常?
- 打开窗体时默认选中第一行,所有行绘制时都用第一行的颜色;
- 键盘下移选中行时,选中行变了,绘制的颜色跟着变;
- 点击行时只有选中的那行会用对应颜色,其他行还是用之前选中行的颜色;
- 滚动时选中行没变化,所以所有行又变回选中行的颜色。
内容的提问来源于stack exchange,提问作者ffert2907
相关产品推荐
相关产品推荐

