TDBGrid 預設欄寬固定,資料過長被截斷、過短浪費空間,使用者須手動拖曳調整,且不記憶設定。
TotWidth。Field.Tag > 0 表示最小寬度),計算可變欄數 ResizableColumnCount。dgColLines)與指示器寬度(dgIndicator)。VarWidth = ClientWidth - TotWidth。VarWidth 給可變欄位,並保護最小寬度 Field.Tag。procedure FixDBGridColumnsWidth(const DBGrid: TDBGrid);
var
i, TotWidth, VarWidth, ResizableColumnCount: Integer;
Col: TColumn;
begin
TotWidth := 0;
ResizableColumnCount := 0;
for i := 0 to DBGrid.Columns.Count - 1 do
begin
TotWidth := TotWidth + DBGrid.Columns[i].Width;
if DBGrid.Columns[i].Field.Tag <> 0 then
Inc(ResizableColumnCount);
end;
if dgColLines in DBGrid.Options then
TotWidth := TotWidth + DBGrid.Columns.Count; // 每欄分隔線 1px
if dgIndicator in DBGrid.Options then
TotWidth := TotWidth + DBGrid.IndicatorWidth;
VarWidth := DBGrid.ClientWidth - TotWidth;
if ResizableColumnCount > 0 then
VarWidth := VarWidth div ResizableColumnCount;
for i := 0 to DBGrid.Columns.Count - 1 do
begin
Col := DBGrid.Columns[i];
if Col.Field.Tag <> 0 then
begin
Col.Width := Col.Width + VarWidth;
if Col.Width < Col.Field.Tag then
Col.Width := Col.Field.Tag; // 最小寬度保護
end;
end;
end;
// FormCreate 設定最小寬度(Tag)
Table1.FieldByName('FirstName').Tag := 40; // 固定 40px
Table1.FieldByName('LastName').Tag := 4 + Canvas.TextWidth(Table1.FieldByName('LastName').DisplayName); // 標題寬度+間距
// FormResize 觸發自適應
procedure TForm1.FormResize(Sender: TObject);
begin
FixDBGridColumnsWidth(DBGrid1);
end;


OnColumnMoved / OnColWidthChange 寫入 Ini/Registry,下次啟動套用。Canvas.TextWidth(Field.AsString) 作為理想寬度(大量資料建議抽樣)。Field.Tag 高位存比例權重,低位存最小寬度。