How to auto fit/scale DBGrid's (or other similar) columns widths according to its contents?

Please_Dont_Bully_Me_SO_Lords picture Please_Dont_Bully_Me_SO_Lords · Nov 8, 2012 · Viewed 23.9k times · Source

I am trying to make a frame with a DBGrid that will serve for more than 10 tables with half of its fields as defaults, and other fields exclusive for each table.

As the space for the columns are limited and I do not want to configure each column of each table manually because it is very poor quality work, I was wondering a way to calculate the width of each column by the largest content of a row inside that column, measured by the own component or by the data set.

Does anyone knows the way? Is there out in the world some custom component with that power? I need a solution that implements increase and decrease of size, according to the the visible data in the all visible columns of the grid. My solution so far had a problem with the painting of the selected cell, witch jumps out of the selected dataset row.

enter image description here


Note: Please, do not close my question. It is not about the fit with the grid's width or the form's width. It is about all the columns width to minimize the horizontal scrollbar, but not necessarily hide it.

Answer

alzaimar picture alzaimar · Nov 8, 2012

What you have to do is to use the grid's canvas to measure the contents of each column and set the column's width accordingly. You can either iterate through the dataset or use the OnColumnDraw-Event to adjust the width on the fly.

Here's a sample (I had to use an offset of 5 pixels)

procedure TForm7.DBGridDrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
Var
  w : Integer;

begin
  w := 5+DBGrid.Canvas.TextExtent(Column.Field.DisplayText).cx;
  if w>column.Width then Column.Width := w;
end;

procedure TForm7.FormActivate(Sender: TObject);
Var
  i : Integer;

begin
  // Initialize width
  for I := 0 to DBGrid.Columns.Count - 1 do
    DBGrid.Columns[i].Width := 5 + DBGrid.Canvas.TextWidth(DBGrid.Columns[i].title.caption)
end;