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

Delphi7中无需使用TextOut,通过onDrawColumnCell修改TDBGrid单元格文本

解决方案:无需TextOut()修改TDBGrid单元格文本(Delphi 7)

核心思路

利用OnDrawColumnCell事件,在单元格绘制前临时修改字段的DisplayText,然后调用DefaultDrawColumnCell让网格自动处理原有样式(颜色、字体、对齐方式),绘制完成后再还原原文本,完全避开坐标计算和TextOut()的使用,且不会修改数据集的实际值。

各场景具体实现

1. 日期字段多格式显示

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  OriginalText: string;
begin
  if Column.FieldName = 'MonthYearCol' then // 需显示MM/yyyy的列
  begin
    OriginalText := Column.Field.DisplayText;
    Column.Field.DisplayText := FormatDateTime('MM/yyyy', Column.Field.AsDateTime);
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
    Column.Field.DisplayText := OriginalText; // 还原原文本
  end
  else if Column.FieldName = 'FullDateCol' then // 需显示MM/dd/yyyy的列
  begin
    OriginalText := Column.Field.DisplayText;
    Column.Field.DisplayText := FormatDateTime('MM/dd/yyyy', Column.Field.AsDateTime);
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
    Column.Field.DisplayText := OriginalText;
  end
  else
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

2. 数值阈值替换文本

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  OriginalText: string;
  Value: Double;
begin
  if Column.FieldName = 'Temperature' then
  begin
    Value := Column.Field.AsFloat;
    OriginalText := Column.Field.DisplayText;
    if Value > 100 then
      Column.Field.DisplayText := 'too high'
    else if Value < 0 then
      Column.Field.DisplayText := 'too low';
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
    Column.Field.DisplayText := OriginalText;
  end
  else
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

3. 布尔值替换显示

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  OriginalText: string;
begin
  if Column.FieldName = 'IsActive' then
  begin
    OriginalText := Column.Field.DisplayText;
    if Column.Field.AsBoolean then
      Column.Field.DisplayText := '启用'
    else
      Column.Field.DisplayText := '禁用';
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
    Column.Field.DisplayText := OriginalText;
  end
  else
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

4. 特定条件清空单元格

你提供的exit方式不可行——直接退出会导致单元格区域未被正确绘制,可能残留旧内容或样式混乱。推荐两种正确实现:

方法1:临时设空文本(保留原有样式)

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  OriginalText: string;
begin
  if (Column.FieldName = 'total') and (Column.Field.Value = 0) then
  begin
    OriginalText := Column.Field.DisplayText;
    Column.Field.DisplayText := '';
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
    Column.Field.DisplayText := OriginalText;
  end
  else
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

方法2:手动绘制空白背景(完全控制显示)

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
begin
  if (Column.FieldName = 'total') and (Column.Field.Value = 0) then
  begin
    // 绘制与网格一致的背景
    DBGrid1.Canvas.Brush.Color := DBGrid1.Color;
    if gdSelected in State then
      DBGrid1.Canvas.Brush.Color := clHighlight;
    DBGrid1.Canvas.FillRect(Rect);
    // 绘制网格边框(保持视觉一致性)
    DBGrid1.Canvas.Pen.Color := DBGrid1.GridLineColor;
    DBGrid1.Canvas.Rectangle(Rect);
  end
  else
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

注意事项

  • 务必将TDBGrid的ReadOnly属性设为True,避免编辑状态下的显示冲突
  • 所有修改仅作用于显示层,不会改变数据集的实际存储值
  • 必须在绘制完成后还原DisplayText,否则会影响其他控件对该字段的显示

内容的提问来源于stack exchange,提问作者jwan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:25:26