[Delphi]DBGrid Column-Width 欄位寬度自動最佳化

[Delphi]DBGrid Column-Width 欄位寬度自動最佳化

DBGrid會以資料長度自行調整寬度,所以Column的寬度,常常落落長,
所以寫一個方法,來自行最佳化。

※原理說明:利用Canvas的方法TextWidth取得文字寬度,進行調整過程中,先以Field的文字進行寬度最佳化後,
                     再以Column->Title->Caption(以避免Field的內容為空值)

   1:    procedure FitDBGridWidth(DBGrid:TInfoDBGrid;MaxRecNo:Integer);
   2:    var FieldIdx, I : Integer;
   3:      MaxFieldLen: Array Of Integer;
   4:      FieldName:Array Of String;
   5:      SavePlace:TBookmark;
   6:      Canvas: TCanvas;
   7:      AfterScroll:TDataSetNotifyEvent;
   8:    begin
   9:      Canvas := DBGrid.Canvas;
  10:      if (DBGrid.DataSource.DataSet.State
  11:                  in [dsInactive, dsInsert, dsEdit])
  12:         or(DBGrid.DataSource.DataSet.IsEmpty = True) then Exit;
  13:      try
  14:        AfterScroll:=DBGrid.DataSource.DataSet.AfterScroll;
  15:        DBGrid.DataSource.DataSet.AfterScroll:=nil;
  16:        with DBGrid.DataSource.DataSet do
  17:        begin
  18:          SavePlace := GetBookmark; //原始位置
  19:          SetLength(MaxFieldLen,DBGrid.DataSource.DataSet.FieldCount);
  20:          SetLength(FieldName,DBGrid.DataSource.DataSet.FieldCount);
  21:          DBGrid.DataSource.DataSet.DisableControls;
  22:          DBGrid.DataSource.DataSet.First;
  23:          while Not DBGrid.DataSource.DataSet.Eof do begin
  24:            For I := 0 to DBGrid.DataSource.DataSet.Fields.Count - 1 DO
  25:            BEGIN
  26:              FieldName[I]:=DBGrid.DataSource.DataSet.Fields[I].FieldName;
  27:              IF (Canvas.TextWidth(DBGrid.DataSource.DataSet.Fields.Fields[I].DisplayText) + 4) > MaxFieldLen[I] Then
  28:                  MaxFieldLen[I] := Canvas.TextWidth(
  29:                    DBGrid.DataSource.DataSet.Fields.Fields[I].DisplayText) + 4
  30:            END;
  31:            DBGrid.DataSource.DataSet.Next;
  32:            if DBGrid.DataSource.DataSet.RecNo>MaxRecNo then Break;
  33:          end;
  34:          DBGrid.DataSource.DataSet.First;
  35:          DBGrid.DataSource.DataSet.EnableControls;
  36:   
  37:          for I := Low(FieldName) to High(FieldName) do
  38:          begin
  39:            FieldIdx:= ColIndexOf(DBGrid, FieldName[I]);
  40:            IF FieldIdx = -1 then Continue;
  41:            IF (DBGrid.Columns.Items[FieldIdx].Visible) then begin
  42:              if MaxFieldLen[I]>(Canvas.TextWidth(DBGrid.Columns[FieldIdx].Title.Caption)+4) then begin
  43:                if MaxFieldLen[I]>300 then
  44:                  DBGrid.Columns.Items[FieldIdx].Width := 300
  45:                else
  46:                  DBGrid.Columns.Items[FieldIdx].Width := MaxFieldLen[I];
  47:              end
  48:              Else
  49:                DBGrid.Columns.Items[FieldIdx].Width:= (Canvas.TextWidth(DBGrid.Columns[FieldIdx].Title.Caption)+4);
  50:            end
  51:            ELSE DBGrid.Columns.Items[FieldIdx].Width := -1;
  52:          end;
  53:          GotoBookmark(SavePlace); //回到 原始位置
  54:          FreeBookmark(SavePlace);
  55:        end;
  56:      finally
  57:        DBGrid.DataSource.DataSet.AfterScroll:=AfterScroll;
  58:      end;
  59:    end;

料理方法:

   1:  //將DBGrid進行欄位寬度最佳化,以前50筆進行取樣
   2:  FitDBGridWidth(grdDetail,50);