You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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事件代码,补充以下关键步骤:

  1. 先绘制单元格背景:避免文字和透明/同色背景重叠
  2. 显式设置Canvas的填充颜色(文字颜色):确保文字和背景有足够对比度
  3. 优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:13:36