You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Delphi 10.2中TDBGrid的OnDrawColumnCell事件数据重叠问题求助

解决Delphi 10.2中TDBGrid OnDrawColumnCell事件数据重叠问题

我之前帮朋友排查过完全一样的问题,根源在于Delphi XE之后的TDBGrid组件在绘制机制上做了性能优化,和Delphi 7的老版本逻辑差异很大——当单元格获得焦点或者处于编辑状态时,默认的绘制流程不会被自定义的OnDrawColumnCell完全覆盖,就会出现新旧内容重叠的情况。

下面给你两种针对性的修复方案,结合你的场景给出具体代码:

方案一:自定义绘制前清空单元格区域

这是最直接的解决方式,在绘制自定义内容前,先用网格背景色填充单元格,彻底清除原有内容:

procedure TYourForm.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  CustomDisplayText: string;
begin
  // 第一步:用网格默认背景色填充单元格,清除原有绘制内容
  DBGrid1.Canvas.Brush.Color := DBGrid1.Color;
  DBGrid1.Canvas.FillRect(Rect);

  // 第二步:处理你的自定义显示逻辑(以LastName列为例)
  if Column.FieldName = 'LastName' then
  begin
    // 替换成你需要的自定义显示值
    CustomDisplayText := '自定义前缀_' + Column.Field.AsString;
    // 绘制文本时添加少量偏移,避免贴边影响美观
    DBGrid1.Canvas.TextOut(Rect.Left + 3, Rect.Top + 2, CustomDisplayText);
  end
  else
  begin
    // 其他列保持默认绘制逻辑
    DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
  end;

  // 可选:手动绘制选中/焦点单元格的边框,保持视觉一致性
  if gdSelected in State then
  begin
    DBGrid1.Canvas.Brush.Color := clHighlight;
    DBGrid1.Canvas.FrameRect(Rect);
  end;
end;

方案二:处理编辑状态的冲突(如果允许单元格编辑)

如果你的网格需要支持编辑,还需要避免编辑控件和自定义绘制的内容冲突:

  • 把需要自定义显示的列的ReadOnly属性设为True,禁止该列进入编辑状态;
  • 如果必须允许编辑,可以在OnEditButtonClick事件中手动弹出编辑框处理,而不是依赖TDBGrid自动创建的编辑控件。

为什么Delphi 7中运行正常?

老版本的TDBGrid在触发OnDrawColumnCell事件时,会先完全清空整个单元格的绘制区域,自定义绘制的内容会直接覆盖所有原有元素;而Delphi 10.2这类新版本为了提升绘制性能,做了局部绘制的优化,只更新需要变化的部分,所以如果自定义绘制没有主动清空区域,就会和之前的内容重叠。

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

火山引擎 最新活动