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?
- Drop a StringGrid component on the form. It always starts out with 1
fixed
row and 1 fixed column.
- In the Object Inspector, set the ColCount and RowCount as
desired..
- Set FixedCols to 0. This is the trick that will let
you resize all the columns with the mouse!
- 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.
- 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;
|