2013-07-07 18 views
5

Ho un TDBGrid. Funziona, ma le colonne mostrate sono molto grandi.Regola Larghezza colonna DBGrid

Come è possibile impostare una "larghezza della colonna di auto-correzione"?

+4

La larghezza di ogni colonna è per impostazione predefinita adattata alle dimensioni dichiarate del campo corrispondente. Se questo non corrisponde alla realtà, dovresti riconsiderare la progettazione del tuo database. –

+0

@Uwe, questo è vero per il conteggio 'DisplayWidth' del campo di' 0' caratteri, che è largo 6px ciascuno con il font Tahoma size 8 (al ridimensionamento predefinito). Se stavi visualizzando, diciamo un 100 di caratteri 'W' (che è 10px di larghezza ciascuno), la larghezza della colonna predefinita sarebbe 400px più stretta di quella effettivamente necessaria (quando' DisplayWidth' sarebbe 100). Quindi potrebbe esserci anche un motivo opposto per l'autoscatto delle larghezze. – TLama

risposta

10

La larghezza di colonna necessaria dipende dalle impostazioni dell'area di disegno delle griglie e dalla lunghezza minima del testo visualizzato di ciascun campo.

procedure FitGrid(Grid: TDBGrid); 
const 
    C_Add=3; 
var 
    ds: TDataSet; 
    bm: TBookmark; 
    i: Integer; 
    w: Integer; 
    a: Array of Integer; 
begin 
    ds := Grid.DataSource.DataSet; 
    if Assigned(ds) then 
    begin 
    ds.DisableControls; 
    bm := ds.GetBookmark; 
    try 
     ds.First; 
     SetLength(a, Grid.Columns.Count); 
     while not ds.Eof do 
     begin 
     for I := 0 to Grid.Columns.Count - 1 do 
     begin 
      if Assigned(Grid.Columns[i].Field) then 
      begin 
      w := Grid.Canvas.TextWidth(ds.FieldByName(Grid.Columns[i].Field.FieldName).DisplayText); 
      if a[i] < w then 
       a[i] := w ; 
      end; 
     end; 
     ds.Next; 
     end; 
     for I := 0 to Grid.Columns.Count - 1 do 
     Grid.Columns[i].Width := a[i] + C_Add; 
     ds.GotoBookmark(bm); 
    finally 
     ds.FreeBookmark(bm); 
     ds.EnableControls; 
    end; 
    end; 
end; 

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    FitGrid(DBgrid1) 
end; 
+5

ZeroMemory non necessario. SetLength inizializza tutti i nuovi membri con zero. –

+0

Buona soluzione. Solo un pignolo: nell'interno 'se a [i] lurker

+0

Che può richiedere molto tempo su un set di dati di grandi dimensioni e barfs quando si dispone di un record randagio con un contenuto molto lungo. Che per inciso sono le ragioni per cui il 'TDBGrid' non ha questo tipo di funzionalità in primo luogo, e Windows Explorer non ridimensiona 'correttamente' in alcune circostanze. –

3

piccola modifica della risposta di bummi per assicurare che il titolo riga (riga 0) non è troncato

procedure FitGrid(Grid: TDBGrid); 
const 
    C_Add=3; 
var 
    ds: TDataSet; 
    bm: TBookmark; 
    i: Integer; 
    w: Integer; 
    a: Array of Integer; 
begin 
    ds := Grid.DataSource.DataSet; 
    if Assigned(ds) then 
    begin 
    ds.DisableControls; 
    bm := ds.GetBookmark; 
    try 
     ds.First; 
     SetLength(a, Grid.Columns.Count); 
     while not ds.Eof do 
     begin 
     for I := 0 to Grid.Columns.Count - 1 do 
     begin 
      if Assigned(Grid.Columns[i].Field) then 
      begin 
      w := Grid.Canvas.TextWidth(ds.FieldByName(Grid.Columns[i].Field.FieldName.).DisplayText); 
      if a[i] < w then 
       a[i] := w ; 
      end; 
     end; 
     ds.Next; 
     end; 
     //if fieldwidth is smaller than Row 0 (field names) fix 
     for I := 0 to Grid.Columns.Count - 1 do 
     begin 
     w := Grid.Canvas.TextWidth(Grid.Columns[i].Field.FieldName); 
     if a[i] < w then 
      a[i] := w ; 
     end; 

     for I := 0 to Grid.Columns.Count - 1 do 
     Grid.Columns[i].Width := a[i] + C_Add; 
     ds.GotoBookmark(bm); 
    finally 
     ds.FreeBookmark(bm); 
     ds.EnableControls; 
    end; 
    end; 
end; 
+0

Ciao, sono abbastanza nuovo da Delphi e vorrei chiederti, per spiegare come funziona in dettaglio. Quali sono le variabili come i, w e un bene per, ecc. Sarò davvero grato. – user2886091

2

piccola modifica della risposta di bummi per assicurare che il titolo riga (riga 0), non viene troncato, e spazio in eccesso sarà assegnato su ogni colonna

procedure FitGrid(Grid: TDBGrid); 
const 
    C_Add = 3; 
var 
    ds: TDataSet; 
    bm: TBookmark; 
    i: Integer; 
    w: Integer; 
    a: array of Integer; 
begin 
    ds := Grid.DataSource.DataSet; 

    if not Assigned(ds) then 
    exit; 

    if Grid.Columns.Count = 0 then 
    exit; 

    ds.DisableControls; 
    bm := ds.GetBookmark; 
    try 
    ds.First; 
    SetLength(a, Grid.Columns.Count); 
    for i := 0 to Grid.Columns.Count - 1 do 
     if Assigned(Grid.Columns[i].Field) then 
     a[i] := Grid.Canvas.TextWidth(Grid.Columns[i].FieldName); 

    while not ds.Eof do 
    begin 

     for i := 0 to Grid.Columns.Count - 1 do 
     begin 
     if not Assigned(Grid.Columns[i].Field) then 
      continue; 

     w := Grid.Canvas.TextWidth(ds.FieldByName(Grid.Columns[i].Field.FieldName).DisplayText); 

     if a[i] < w then 
      a[i] := w; 
     end; 
     ds.Next; 
    end; 

    w := 0; 
    for i := 0 to Grid.Columns.Count - 1 do 
    begin 
     Grid.Columns[i].Width := a[i] + C_Add; 
     inc(w, a[i] + C_Add); 
    end; 

    w := (Grid.ClientWidth - w - 20) div (Grid.Columns.Count); 

    if w > 0 then 
     for i := 0 to Grid.Columns.Count - 1 do 
     Grid.Columns[i].Width := Grid.Columns[i].Width + w; 


    ds.GotoBookmark(bm); 
    finally 
    ds.FreeBookmark(bm); 
    ds.EnableControls; 
    end; 
end; 
0

modifica minore di bummi di, TheSteven di risposte e Jens' per assicurare che il titolo riga (riga 0), non viene troncato, e spazio in eccesso sarà allo in ogni colonna, e rendere visibile le colonne nell'account.

procedure FitGrid(const Grid: TDBGrid; const CoverWhiteSpace: Boolean = True); 
const 
    C_Add=3; 
var 
    DS: TDataSet; 
    BM: TBookmark; 
    I, W, VisibleColumnsCount: Integer; 
    A: array of Integer; 
    VisibleColumns: array of TColumn; 
begin 
    DS := Grid.DataSource.DataSet; 
    if Assigned(DS) then 
    begin 
    VisibleColumnsCount := 0; 
    SetLength(VisibleColumns, Grid.Columns.Count); 
    for I := 0 to Grid.Columns.Count - 1 do 
     if Assigned(Grid.Columns[I].Field) and (Grid.Columns[I].Visible) then 
     begin 
     VisibleColumns[VisibleColumnsCount] := Grid.Columns[I]; 
     Inc(VisibleColumnsCount); 
     end; 
    SetLength(VisibleColumns, VisibleColumnsCount); 

    DS.DisableControls; 
    BM := DS.GetBookmark; 
    try 
     DS.First; 
     SetLength(A, VisibleColumnsCount); 
     while not DS.Eof do 
     begin 
     for I := 0 to VisibleColumnsCount - 1 do 
     begin 
      W := Grid.Canvas.TextWidth(DS.FieldByName(VisibleColumns[I].Field.FieldName).DisplayText); 
      if A[I] < W then 
       A[I] := W; 
     end; 
     DS.Next; 
     end; 
     //if fieldwidth is smaller than Row 0 (field names) fix 
     for I := 0 to VisibleColumnsCount - 1 do 
     begin 
     W := Grid.Canvas.TextWidth(VisibleColumns[I].Field.FieldName); 
     if A[I] < W then 
      A[I] := W; 
     end; 

     W := 0; 
     if CoverWhiteSpace then 
     begin 
     for I := 0 to VisibleColumnsCount - 1 do 
      Inc(W, A[I] + C_Add); 
     W := (Grid.ClientWidth - W - 20) div VisibleColumnsCount; 
     if W < 0 then 
      W := 0; 
     end; 

     for I := 0 to VisibleColumnsCount - 1 do 
     VisibleColumns[I].Width := A[I] + C_Add + W; 
     DS.GotoBookmark(BM); 
    finally 
     DS.FreeBookmark(BM); 
     DS.EnableControls; 
    end; 
    end; 
end; 
Problemi correlati