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

Delphi 11 VCL运行时样式下DBGrid单元格颜色获取与修改问题

Delphi 11 VCL DBGrid样式相关问题解决方案

问题1:运行时获取单元格即将绘制的颜色值(含字体颜色)

要获取当前样式下DBGrid单元格的默认绘制颜色,需通过VCL样式服务TStyleServices读取对应样式元素的颜色值,同时要区分单元格的状态(普通、交替行、选中):

  • 先通过StyleServices.Enabled确认样式已启用
  • 根据单元格状态匹配对应的样式元素:
    • 普通未选中单元格:背景色sGridCell、字体色sGridCellFont
    • 交替行单元格:背景色sGridAltCell、字体色sGridAltCellFont
    • 选中单元格:背景色sGridSelectedCell、字体色sGridSelectedCellFont

示例代码(可放在OnDrawColumnCell事件中):

var
  StyleSvc: TStyleServices;
  CellColor, FontColor: TColor;
begin
  StyleSvc := TStyleServices(StyleServices);
  if StyleSvc.Enabled then
  begin
    // 判断单元格状态
    if (gdSelected in State) then
    begin
      CellColor := StyleSvc.GetStyleColor(sGridSelectedCell);
      FontColor := StyleSvc.GetStyleColor(sGridSelectedCellFont);
    end
    else if (Column.Field.DataSet.RecNo mod 2) = 0 then
    begin
      CellColor := StyleSvc.GetStyleColor(sGridAltCell);
      FontColor := StyleSvc.GetStyleColor(sGridAltCellFont);
    end
    else
    begin
      CellColor := StyleSvc.GetStyleColor(sGridCell);
      FontColor := StyleSvc.GetStyleColor(sGridCellFont);
    end;
    // CellColor和FontColor即为当前样式下的默认绘制颜色
  end
  else
  begin
    // 未启用样式时,直接读取DBGrid自身属性
    CellColor := DBGrid1.Color;
    FontColor := DBGrid1.Font.Color;
  end;
end;

问题2:运行时修改当前样式的网格及字体颜色

如果不想通过OnDrawColumnCell硬绘单元格,可直接修改当前VCL样式的网格元素颜色,这样样式切换后也能保持自定义配色,步骤如下:

  1. 创建当前活动样式的副本,避免修改原始样式文件
  2. 修改副本中对应网格元素的颜色值
  3. 将修改后的副本设置为当前样式

示例代码:

var
  CustomStyle: TCustomStyleServices;
begin
  if StyleServices.Enabled then
  begin
    CustomStyle := TCustomStyleServices.Create;
    try
      // 加载当前样式的副本
      CustomStyle.LoadFromResourceName(HInstance, StyleServices.Name);
      
      // 修改网格元素颜色
      CustomStyle.SetStyleColor(sGridCell, clSkyBlue);        // 普通单元格背景
      CustomStyle.SetStyleColor(sGridCellFont, clNavy);       // 普通单元格字体
      CustomStyle.SetStyleColor(sGridSelectedCell, clNavy);   // 选中单元格背景
      CustomStyle.SetStyleColor(sGridSelectedCellFont, clWhite); // 选中单元格字体
      CustomStyle.SetStyleColor(sGridAltCell, clLightYellow); // 交替行背景
      CustomStyle.SetStyleColor(sGridAltCellFont, clMaroon);  // 交替行字体
      
      // 应用修改后的样式
      TStyleManager.SetStyle(CustomStyle);
    finally
      CustomStyle.Free;
    end;
  end;
end;

如果需要结合字段值做动态配色(既保留样式基础,又针对特定数据调整),可在OnDrawColumnCell中先获取样式默认颜色,再根据字段值修改后绘制:

procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  StyleSvc: TStyleServices;
  CellColor, FontColor: TColor;
begin
  StyleSvc := TStyleServices(StyleServices);
  if StyleSvc.Enabled then
  begin
    // 获取样式默认颜色(同问题1的判断逻辑)
    if (gdSelected in State) then
    begin
      CellColor := StyleSvc.GetStyleColor(sGridSelectedCell);
      FontColor := StyleSvc.GetStyleColor(sGridSelectedCellFont);
    end
    else if (Column.Field.DataSet.RecNo mod 2) = 0 then
    begin
      CellColor := StyleSvc.GetStyleColor(sGridAltCell);
      FontColor := StyleSvc.GetStyleColor(sGridAltCellFont);
    end
    else
    begin
      CellColor := StyleSvc.GetStyleColor(sGridCell);
      FontColor := StyleSvc.GetStyleColor(sGridCellFont);
    end;
    
    // 根据字段值调整颜色
    if Column.Field.AsString = '重要数据' then
    begin
      CellColor := clRed;
      FontColor := clWhite;
    end;
  end
  else
  begin
    CellColor := DBGrid1.Color;
    FontColor := DBGrid1.Font.Color;
    if Column.Field.AsString = '重要数据' then
    begin
      CellColor := clRed;
      FontColor := clWhite;
    end;
  end;
  
  // 绘制单元格
  DBGrid1.Canvas.Brush.Color := CellColor;
  DBGrid1.Canvas.Font.Color := FontColor;
  DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:35:24