delphitdbgrid

Setting TDBGrid visible rows


I want to adjust a TDBGrid height given a VisibleRows parameter. the grid may or may not have titles.

Suppose I select 100 records from the db, but I want the grid height to adjust to show the first 10 rows (make them visible). the dataset will still hold 100 records.

i.e.

procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
begin
  ...
  DBGrid.Height := ???
end;

I know how to get the visible rows:

type
  TCustomGridHack = class(TCustomGrid);

function GetVisibleRows(DBGrid: TCustomDBGrid): Integer;
begin
   Result := TCustomGridHack(DBGrid).VisibleRowCount;
end;

But, is there a way to set the VisibleRowCount?


Solution

  • This seems to work (maybe could be optimized more):

    type
      TCustomDBGridHack = class(TCustomDBGrid);
    
    procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
    var
      TitleHeight, RowHeight: Integer;
    begin
      with TCustomDBGridHack(DBGrid) do
      begin
        if dgTitles in Options then
        begin
          TitleHeight := RowHeights[0] + GridLineWidth;
          RowHeight := RowHeights[1] + GridLineWidth;
        end
        else
        begin
          TitleHeight := 0;
          RowHeight := RowHeights[0] + GridLineWidth;
        end;
      end;
      DBGrid.ClientHeight := TitleHeight + (RowHeight * VisibleRows) + 1;
    end;
    

    Or by using TGridDrawInfo as suggested by @nil. It produces more accurate results (I modified it a bit):

    procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
    var
      DrawInfo: TGridDrawInfo;
      TitleHeight, RowHeight: Integer;
    begin
      with TCustomDBGridHack(DBGrid) do
      begin
        CalcDrawInfo(DrawInfo);
        TitleHeight := DrawInfo.Vert.FixedBoundary;
        RowHeight := RowHeights[DrawInfo.Vert.FirstGridCell] + DrawInfo.Vert.EffectiveLineWidth;
      end;
      DBGrid.ClientHeight := TitleHeight + (RowHeight * VisibleRows) + 1;
    end;
    

    As mentioned by @nil, RowHeight could be also calculated with:

    RowHeight := DrawInfo.Vert.GetExtent(DrawInfo.Vert.FirstGridCell) + DrawInfo.Vert.EffectiveLineWidth; 
    

    I haven't noticed any difference though. (should be further investigated).

    The above could be further improved to make the TDBGrid scroll-bars adjust better:

    procedure SetVisibleRows(DBGrid: TCustomDBGrid; VisibleRows: Integer);
    var
      DrawInfo: TGridDrawInfo;
      TitleHeight, RowHeight: Integer;
      HasActiveDataSet: Boolean;
    begin
      if VisibleRows < 0 then VisibleRows := 0;
      HasActiveDataSet := Assigned(DBGrid.DataSource) and
        Assigned(DBGrid.DataSource.DataSet) and
        DBGrid.DataSource.DataSet.Active;
      if HasActiveDataSet then
        DBGrid.DataSource.DataSet.DisableControls;
      try
        with TCustomDBGridHack(DBGrid) do
        begin
          CalcDrawInfo(DrawInfo);
          TitleHeight :=  DrawInfo.Vert.FixedBoundary;
          RowHeight := RowHeights[DrawInfo.Vert.FirstGridCell] + DrawInfo.Vert.EffectiveLineWidth;      
        end;
        DBGrid.ClientHeight := TitleHeight + (RowHeight * VisibleRows) + 1;
      finally
        if HasActiveDataSet then
          DBGrid.DataSource.DataSet.EnableControls;
      end;
    end;