views:

638

answers:

5

I've got a TDBGrid with predefined columns, and I just can't get the width right. I can mess with the Width property of the columns in the Form Designer and get the width to look just right at design time, but at runtime, for whatever reason, the columns tend to be significantly wider, and I end up with a scroll bar at the bottom of the grid. Is there any way to get make the columns size themselves correctly without all the trial-and-error, especially if the grid only has one or two of them?

A: 

You can do that, but you have to check the width of all fields for all records that you potentially can display.

Given the fact that there are still plenty of applications that hardly filter their record set, this can mean that you need to check a zillion records, just to get rid of the scrollbar.

Have you ever considered that you might just want to display too much information at once?

A possible alternative is to show a hint text for fields that do not fit in their column?

I have used such an alternative, but need to check the sources; I can get you some sample code tomorrow.

--jeroen

Jeroen Pluimers
You seem to be misinterpreting my request. I'm not trying to make the columns as wide as the data in the field they display, I'm trying to make the columns *exactly as wide as the width of the grid control.*
Mason Wheeler
Ah - sorry for that :-)
Jeroen Pluimers
+2  A: 

I use this procedure inside forms OnResize event

procedure AutoStretchDBGridColumns(Grid: TDBGrid; Columns, MinWidths: Array of integer);
var
  x, i, ww: integer;
begin
  // Stretches TDBGrid columns
  // Columns contains columns to stretch
  // MinWidths contains columns minimum widhts
  // To stretch grids columns 1,2 and 5 automatically and set minimum widths to 80, 150 and 150 call
  // AutoStretchDBGridColumns(DBGrid1, [1,2,5], [80, 150, 150]);
  Assert(Length(Columns) = Length(MinWidths), 'Length(Columns) <> Length(MinWidths)');
  ww := 0;
  for i := 0 to Grid.Columns.Count - 1 do
  begin
    if Grid.Columns[i].Visible then
      ww := ww + Grid.Columns[i].Width + 1; //** +1 for grid line width
  end;
  if dgIndicator in Grid.Options then
    ww := ww + IndicatorWidth;
  x := (Grid.ClientWidth - ww) div Length(Columns);
  for i := 0 to  High(Columns) do
    Grid.Columns[Columns[i]].Width := Max(Grid.Columns[Columns[i]].Width + x, MinWidths[i]);
end;

It has some flaws, but works quite well.

JP
A: 

JP's answer is a pretty good solution. You need to manually stretch or shrink the columns as necessary to make it fit in the window. There is a windows API call to get the vertical scroll bar width. Then you can look at the visible rows to see if the vertical scroll bar is being shown.

Another technique is to figure out the width of each column relative to each other. Then when you resize them maintain the same ratio.

Jim McKeeth
A: 

You may have a look at the answers to this question.

Perhaps the protected CalcDrawInfo method may help here.

Uwe Raabe