Mirror

How to autosize columns in a TDBGrid (Views: 14)


Problem/Question/Abstract:

How to autosize columns in a TDBGrid

Answer:

This procedure will let you define the general layout of the grid at design-time by creating static columns for the grid, confident that proportions between columns will be maintained at run-time regardless of whether the user resizes the grid. To enable this new feature, disable column sizing for the grid (dgColSizing set to False in the grid options) and make a call to the new procedure in the OnResize event of the form holding the grid.


unit AdjustGrid;

interface

uses
  Windows, Forms, DBGrids;

procedure AdjustColumnWidths(DBGrid: TDBGrid);

implementation

procedure AdjustColumnWidths(DBGrid: TDBGrid);
var
  TotalColumnWidth, ColumnCount, GridClientWidth, Filler, i: Integer;
begin
  ColumnCount := DBGrid.Columns.Count;
  if ColumnCount = 0 then
    Exit;
  {compute total width used by grid columns and vertical lines if any}
  TotalColumnWidth := 0;
  for i := 0 to ColumnCount - 1 do
    TotalColumnWidth := TotalColumnWidth + DBGrid.Columns[i].Width;
  if dgColLines in DBGrid.Options then
    {include vertical lines in total (one per column)}
    TotalColumnWidth := TotalColumnWidth + ColumnCount;
  {compute grid client width by excluding vertical scrollbar, grid indicator and grid border}
  GridClientWidth := DBGrid.Width - GetSystemMetrics(SM_CXVSCROLL);
  if dgIndicator in DBGrid.Options then
  begin
    GridClientWidth := GridClientWidth - IndicatorWidth;
    if dgColLines in DBGrid.Options then
      Dec(GridClientWidth);
  end;
  if DBGrid.BorderStyle = bsSingle then
  begin
    if DBGrid.Ctl3D then {border is sunken (vertical border is 2 pixels wide)}
      GridClientWidth := GridClientWidth - 4
    else {border is one-dimensional (vertical border is one pixel wide)}
      GridClientWidth := GridClientWidth - 2;
  end;
  {adjust column widths}
  if TotalColumnWidth < GridClientWidth then
  begin
    Filler := (GridClientWidth - TotalColumnWidth) div ColumnCount;
    for i := 0 to ColumnCount - 1 do
      DBGrid.Columns[i].Width := DBGrid.Columns[i].Width + Filler;
  end
  else if TotalColumnWidth > GridClientWidth then
  begin
    Filler := (TotalColumnWidth - GridClientWidth) div ColumnCount;
    if (TotalColumnWidth - GridClientWidth) mod ColumnCount <> 0 then
      Inc(Filler);
    for i := 0 to ColumnCount - 1 do
      DBGrid.Columns[i].Width := DBGrid.Columns[i].Width - Filler;
  end;
end;

<< Back to main page