Delphi StringGrid 显示不需要的列间距

问题描述

Delphi TStringGrid 在 Embracedero Delphi 10.4 中显示不正确(带有不需要的列间距)。我尝试了设置中的所有内容 - 禁用边距、禁用 Ctl3D、字体设置,... - 我也尝试创建一个全新的 StringGrid,但列间距仍然存在问题。

重现代码

procedure TForm5.StringGrid1DrawCell(Sender: TObject; ACol,ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  if ARow = 0 then
  begin
    StringGrid1.Canvas.Brush.Color := $808080;
    StringGrid1.Canvas.FillRect(Rect)
  end;
end;

Unwanted column spacing example in Delphi StringGrid

解决方法

众所周知,Rect.LeftOnDrawCell 事件中单元格的 TStringGrid 偏移了 4 个像素。可能(但未记录)使输出文本数据更容易,这需要与单元格边框的小偏移。

注意 TDrawGrid 没有这个偏移量。

对于单元格的背景绘制,您可以使用 CellRect() 函数

procedure TForm5.StringGrid1DrawCell(Sender: TObject; ACol,ARow: Integer;
  Rect: TRect; State: TGridDrawState);
begin
  with Sender as TStringGrid do
  begin
    if ARow = 0 then
    begin
      Canvas.Brush.Color := $C0C0C0;
      Canvas.FillRect(CellRect(ACol,ARow));
    end;

    // text output using `Rect` follows
    // ...
  end;
end;
,

我在表单上放置了一个 TStringGrid 并使用您显示的代码分配了一个 OnDrawCell 事件,但这并不能完全重现您的问题:我只在单元格之间未绘制一个像素。

为了解决这个问题,我将矩形的宽度和高度放大了一个像素:

procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol,ARow: Integer;
    Rect: TRect; State: TGridDrawState);
var
    R : TRect;
begin
    R := Rect;
    Inc(R.Right);
    Inc(R.Bottom);
    if ARow = 0 then
        StringGrid1.Canvas.Brush.Color := $808080
    else
        StringGrid1.Canvas.Brush.Color := $A0A0A0;

    StringGrid1.Canvas.FillRect(R)
end;

如您所见,我添加了一个检查以绘制大于 0 的行,以查看行方向上的相同行为。