Delphi tutorials »

StringGrid Column widths

 
ColWidths property of a StringGrid

How to set the width of an individual column of a StringGrid? Many beginner Delphi programmers have struggled with this appearently simple task. It's quite annoying that you can't do this at design time with the Object Inspector. Seems like individual column widths are only accessible at runtime via the array ColWidths, for example:

StringGrid1.ColWidths[0] := 100;

Resizing a column with the mouse

You can resize the width of each column with the mouse, both at design time as well as at runtime. If you put the cursor on the line between two cells of the first row, you get a double headed arrow cursor. Now drag the column narrower or wider. But... this feature doesn't work always! A few conditions have to be met, and this is not so obvious from Delphi's help files:

  • The StringGrid must have at least one fixed row.
     
  • At runtime, resizing the columns with the mouse only works if the property Options contains goColSizing (not necessary at design time).
     
  • You can not resize a fixed column with the mouse.

DefaultColWidth property

If the width of a StringGrid column has not been set, by resizing with the mouse or by using the ColWidths property, it's defined by DefaultColWidth.

You can set this property at design time with the Object Inspector, as well as at runtime through your code.
Important note: when you change DefaultColWidth, the widths of ALL the columns are changed, also those that were resized previously with the mouse or via the ColWidths property!

A practical example

In the light of all the above, how would you quickly set up a stringgrid with one or more fixed columns?

  1. Drop a StringGrid component on the form. It always starts out with 1 fixed row and 1 fixed column.
  2. In the Object Inspector, set the ColCount and RowCount as desired..
  3. Set FixedCols to 0. This is the trick that will let you resize all the columns with the mouse!
  4. Select the stringgrid by clicking on it. Next, resize the individual columns by dragging the vertical lines in the top row (fixed row). Also adjust the total width of the stringgrid as desired.
  5. In the Object Inspector, set FixedCols to what you really want.

Auto-size your StringGrid

The following Delphi source code demonstrates how to automatically adapt the width of a column to the width of its widest cell contents. It's "auto-sizing" of a column as it were:

procedure TForm1.AutoSizeCol(Grid: TStringGrid;
Column: integer);
var
  i, W, WMax: integer;
begin
  WMax := 0; 
  for i := 0 to (Grid.RowCount - 1) do begin
    W := Grid.Canvas.TextWidth(Grid.Cells[Column, i]);
    if W > WMax then 
      WMax := W;
  end;
  Grid.ColWidths[Column] := WMax + 5;
end;

How to "auto size" the first column with this procedure:

procedure TForm1.Button1Click(Sender: TObject);
begin
  AutoSizeCol(StringGrid1, 0);
end;

How to "autosize" all of the columns:

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to StringGrid1.ColCount - 1 do
    AutoSizeCol(StringGrid1, 0);
end;

Adapt the StringGrid column widths to the Header row

Here's another interesting procedure, that adjusts the column widths to the column "headers". By "headers" we mean: the cells of the fixed row. Of course, only execute this procedure after you've set some text into the fixed row cells.

procedure TForm1.SizeColsToHeaders(Grid:
TStringGrid);
var
  Col: integer;
begin
  for Col := 0 to (Grid.ColCount - 1) do
    Grid.ColWidths[Col] := 
      Grid.Canvas.TextWidth(Grid.Cells[Col, 0]) + 5;
end;

 


Crash Course Delphi :: Database Tutorial :: Source Code and Tutorials
FAQ :: DC Library :: Tips :: Downloads :: Links