2

我有一个网格组件(DBGrid),上面有很多列。由于大量的列,创建了一个滚动条,因此网格的某些部分仍然隐藏。我需要找出 DBGrid 的实际宽度是多少,包括由于滚动条而未显示的部分。但是 Width 属性只给出了组件本身的宽度。有人有什么想法吗?

4

4 回答 4

2

TDBGrid有财产Columns。每个列都有自己的Width属性。因此,您可以遍历所有列并总结它们的宽度。

像这样:

function TotalColumnsWidth(var AGrid: TDBGrid);
var
  i: Integer;
begin
  Result := 0;
  for i := to AGrid.Columns.Count - 1 do
    Result := Result + AGrid.Columns[i].Width;
end;
于 2009-11-11T17:50:26.507 回答
1

也许这可能会有所帮助。它是自动调整最后一列大小的 TDBGrid 类助手的一部分,因此网格没有空白空间。应该很容易适应您的需求。

您可能会注意到,CalcDrawInfo 方法正是您所寻求的。由于它受到保护,您可以使用类助手或通常的受保护黑客来获取它。

procedure TDbGridHelper.AutoSizeLastColumn;
var
  DrawInfo: TGridDrawInfo;
  ColNo: Integer;
begin
  ColNo := ColCount - 1;
  CalcDrawInfo(DrawInfo);
  if (DrawInfo.Horz.LastFullVisibleCell < ColNo - 1) then Exit;

  if (DrawInfo.Horz.LastFullVisibleCell < ColNo) then
    ColWidths[ColNo] := DrawInfo.Horz.GridBoundary - DrawInfo.Horz.FullVisBoundary
  else
    ColWidths[ColNo] := ColWidths[ColNo] + DrawInfo.Horz.GridExtent - DrawInfo.Horz.FullVisBoundary
end;
于 2009-11-11T21:29:13.613 回答
0

我想我已经找到了解决方案(虽然看起来有点奇怪)。为了找到DBgrid的列宽和实际宽度之间的差异(即找到最后一列之后剩余的空白区域的宽度),我们需要跟踪现在左侧显示的是哪一列(当前列是什么滚动到)。我们可以使用 OnDrawColumnCell 事件来做到这一点,因为它只会绘制现在滚动的列。然后我们需要计算所有可见列的宽度之和,然后从 DBGrid 的宽度中减去它。PS对不起英语不好

防爆代码:

     For i:=0 to Last do
     if Vis[i] then
     Begin
      Sum:=Sum+DBG.Columns[i].Width;
      Inc(Cnt);
     End;

     if dgColLines in DBG.Options then
     Sum := Sum + Cnt;

  //add indicator column width
    if dgIndicator in DBG.Options then
    Sum := Sum + IndicatorWidth;
    Dif:=DBG.ClientWidth - Sum;
于 2009-11-11T19:02:16.840 回答
0

以下是我们过去使用过的功能。它会根据字体考虑数据的宽度,如果垂直线可见,也会对其进行补偿

function GridTextWidth(fntFont : TFont; const sString : OpenString) :
  integer;
var
  f: TForm;
begin
  try
    f:=TForm.Create(nil);
    f.Font:=fntFont;
    result:=f.canvas.textwidth(sstring);
  finally
    f.Free;
    end;
end;




function CalcGridWidth(dbg : TDBGrid { the grid to meaure }): integer; { the "exact" width }
const cMEASURE_CHAR   = '0';
      iEXTRA_COL_PIX  = 4;
      iINDICATOR_WIDE = 11;
var i, iColumns, iColWidth, iTitleWidth, iCharWidth : integer;
begin
  iColumns := 0;
  result   := GetSystemMetrics(SM_CXVSCROLL);

  iCharWidth := GridTextWidth(dbg.font,cMeasure_char);

  with dbg.dataSource.dataSet do begin
    DisableControls;
    for i := 0 to FieldCount - 1 do with Fields[i] do
      if visible then
      begin
        iColWidth := iCharWidth * DisplayWidth;
        if dgTitles in dbg.Options then begin
          ititlewidth:=GridTextWidth(dbg.titlefont,displaylabel);
          if iColWidth < iTitleWidth then
            iColWidth := iTitleWidth;
        end;
        inc(iColumns, 1);
        inc(result, iColWidth + iEXTRA_COL_PIX);
      end;
      EnableControls;
    end;

  if dgIndicator in dbg.Options then
  begin
    inc(iColumns, 1);
    inc(result, iINDICATOR_WIDE);
  end;
  if dgColLines in dbg.Options then
    inc(result, iColumns)
  else
    inc(result, 1);
end;
于 2009-11-11T19:25:44.050 回答