Delphi 10.3 FireMonkey自定义绘制Grid时Canvas.FillText失效
解决FireMonkey TGrid自绘时Canvas.FillText不显示文字的问题
我之前踩过FireMonkey Grid自绘的不少坑,结合你的描述和代码来看,问题核心在于**DefaultDrawing=False时,你没有手动管理Canvas的绘制状态**——FireMonkey不会帮你做默认的颜色、背景等基础设置,导致文字要么和背景色重叠看不见,要么绘制参数逻辑有偏差。
核心原因拆解
- 当
DefaultDrawing=True时,TGrid会先完成整套默认绘制(包括背景、文字层),再触发你的OnDrawColumnCell事件。这时候你的自定义文字会被默认的半透明背景层覆盖,所以出现颜色异常、文字发淡的情况;如果绑定了OnGetCellValue,Grid会自动用默认逻辑绘制文字,所以能看到内容,但不符合你自定义绘制的需求。 - 当
DefaultDrawing=False时,TGrid完全放弃默认绘制流程,所有内容(背景、边框、文字)都需要你在事件里手动实现。你之前的代码只处理了文字绘制,但没有设置Canvas的填充颜色(也就是文字颜色),也没有绘制单元格背景,导致文字颜色可能和Canvas默认背景色一致,自然看不见;点击单元格时,Grid的选中状态会临时改变Canvas的颜色,所以文字才会短暂显示。
具体解决方案
修改你的OnDrawColumnCell事件代码,补充以下关键步骤:
- 先绘制单元格背景:避免文字和透明/同色背景重叠
- 显式设置Canvas的填充颜色(文字颜色):确保文字和背景有足够对比度
- 优化FillText的调用逻辑:用单元格边界配合对齐参数,简化位置计算
修改后的代码示例:
procedure TFormFolderCptPairArray.Grid1DrawColumnCell1(Sender: TObject; const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF; const Row: Integer; const Value: TValue; const State: TGridDrawStates); var Grid: TGrid; ColIndex, RowIndex: integer; CellStr: string; TextAlign: TTextAlign; begin Grid:= Sender as TGrid; ColIndex:= Column.Index; RowIndex:= Row; GetGridCellText(ColIndex, RowIndex, CellStr); // 1. 绘制单元格背景(区分奇偶行、选中状态) if TGridDrawState.Selected in State then Canvas.Fill.Color := TAlphaColors.LightSteelBlue else if RowIndex mod 2 = 0 then Canvas.Fill.Color := TAlphaColors.White else Canvas.Fill.Color := TAlphaColors.LightGray; Canvas.FillRect(Bounds, 0, 0, [], 1.0); if CellStr<>'' then begin // 2. 设置文字颜色(确保和背景有对比度) Canvas.Fill.Color := TAlphaColors.Black; // 可选:自定义字体属性 // Canvas.Font.Size := 12; // Canvas.Font.Style := [TFontStyle.fsBold]; // 3. 确定文字对齐方式 if ColIndex=0 then TextAlign := TTextAlign.Center else case (ColIndex-1) mod CFolderFieldCount of 0: TextAlign := TTextAlign.Leading; 1..4: TextAlign := TTextAlign.Center; 5: TextAlign := TTextAlign.Trailing; end; // 4. 绘制文字(用单元格边界+对齐参数,简化位置计算) Canvas.FillText( Bounds, CellStr, True, 1.0, [], TextAlign, TTextAlign.Center // 垂直居中 ); end; end;
额外注意事项
- 如果你需要单元格边框,可以在绘制背景后调用
Canvas.StrokeRect实现,记得先设置Canvas.Stroke.Color。 - FireMonkey的Canvas是状态驱动的,每次绘制前最好显式设置
Fill.Color、Stroke.Color等属性,避免上一次绘制的状态残留影响当前效果。 - 调试时可以先把文字颜色设为鲜艳的红色(
TAlphaColors.Red),确认能显示后再调整为正常颜色,方便排查位置或颜色匹配问题。
内容的提问来源于stack exchange,提问作者user11935527
相关产品推荐
相关产品推荐

