Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 238
NaN Avatar asked Nov 08 '12 16:11

NaN


1 Answers

EDITED:

My first code was about fit the columns inside the grid with, with this new code, AutoSizeColumns reads the records to calc the width of each column until MaxRows or Dataset.Eof:

class function TDBGridHelper.AutoSizeColumns(DBGrid: TDBGrid; const MaxRows: Integer = 25): Integer;

var
  DataSet: TDataSet;
  Bookmark: TBookmark;
  Count, I: Integer;
  ColumnsWidth: array of Integer;
begin
  SetLength(ColumnsWidth, DBGrid.Columns.Count);
  for I := 0 to DBGrid.Columns.Count - 1 do
    if DBGrid.Columns[I].Visible then
      ColumnsWidth[I] := DBGrid.Canvas.TextWidth(DBGrid.Columns[I].Title.Caption + '   ')
    else
      ColumnsWidth[I] := 0;
  if DBGrid.DataSource <> nil then
    DataSet := DBGrid.DataSource.DataSet
  else
    DataSet := nil;
  if (DataSet <> nil) and DataSet.Active then
  begin
    Bookmark := DataSet.GetBookmark;
    DataSet.DisableControls;
    try
      Count := 0;
      DataSet.First;
      while not DataSet.Eof and (Count < MaxRows) do
      begin
        for I := 0 to DBGrid.Columns.Count - 1 do
          if DBGrid.Columns[I].Visible then
            ColumnsWidth[I] := Max(ColumnsWidth[I], DBGrid.Canvas.TextWidth(
              DBGrid.Columns[I].Field.Text));
        Inc(Count);
        DataSet.Next;
      end;
    finally
      DataSet.GotoBookmark(Bookmark);
      DataSet.FreeBookmark(Bookmark);
      DataSet.EnableControls;
    end;
  end;
  Count := 0;
  for I := 0 to DBGrid.Columns.Count - 1 do
    if DBGrid.Columns[I].Visible then
    begin
      DBGrid.Columns[I].Width := ColumnsWidth[I];
      Inc(Count, ColumnsWidth[I]);
    end;
  Result := Count - DBGrid.ClientWidth;
end;

I call it in the DataSet.AfterOpen event:

TGridHelper.AutoSizeColumns(MyDBGrid);
like image 177
Cesar Romero Avatar answered Oct 23 '22 09:10

Cesar Romero