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样式的网格元素颜色,这样样式切换后也能保持自定义配色,步骤如下:
- 创建当前活动样式的副本,避免修改原始样式文件
- 修改副本中对应网格元素的颜色值
- 将修改后的副本设置为当前样式
示例代码:
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
相关产品推荐
相关产品推荐

