Ich habe ein TDBGrid. Es funktioniert, aber die Spalten sind sehr groß.Adjust Spaltenbreite DBGrid
Wie kann ich eine "auto-fix column width" einstellen?
Ich habe ein TDBGrid. Es funktioniert, aber die Spalten sind sehr groß.Adjust Spaltenbreite DBGrid
Wie kann ich eine "auto-fix column width" einstellen?
Die erforderliche Spaltenbreite hängt von den Einstellungen der Grids-Zeichenfläche und der maximalen Länge des Anzeigetextes jedes Felds ab.
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;
ZeroMemory wird nicht benötigt. SetLength initialisiert alle neuen Mitglieder mit Null. –
Gute Lösung. Nur eine kleine Auswahl: Im inneren 'if a [i]
Das kann bei einem großen Datensatz sehr lange dauern, und wenn Sie einen streunenden Datensatz mit einem sehr langen Inhalt haben, wird dieser Fehler behoben. Was übrigens die Gründe sind, warum das 'TDBGrid' überhaupt nicht über diese Funktionalität verfügt und Windows Explorer unter Umständen auch nicht 'richtig' skaliert. –
Minor Modifikation von Bummi Antwort, um sicherzustellen, dass Titel Row (Zeile 0)
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;
Hallo, ich bin ziemlich neu in Delphi und ich möchte dich bitten zu erklären, wie das im Detail funktioniert. Was sind Variablen wie ich, w und ein Gut für ect. Ich werde wirklich dankbar sein. – user2886091
Minor Modifikation von Bummi Antwort nicht abgeschnitten wird, um sicherzustellen, dass Titel Row (Zeile 0) nicht abgeschnitten, und überschüssiger Raum wird auf jeder Spalte zugeordnet wird
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;
Minor Modifikation von Bummi des, TheSteven den und Jens Antworten, um sicherzustellen, dass Titel Row (Zeile 0) nicht abgeschnitten, und die überschüssige Raum wird allo in jeder Spalte angegeben werden, und Sichtbarkeit der Spalten berücksichtigen.
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;
Die Breite jeder Spalte wird standardmäßig auf die angegebene Größe des entsprechenden Felds angepasst. Wenn dies nicht mit der Realität übereinstimmt, sollten Sie Ihr Datenbankdesign überdenken. –
@Uwe, das ist wahr für die "DisplayWidth" -Zahl des Feldes von '0' Zeichen, die 6px breit sind, jedes mit Tahoma Schriftgröße 8 (bei Standardskalierung). Wenn Sie eine 100 von 'W'-Zeichen anzeigen (die jeweils 10px breit ist), wäre die Standardspaltenbreite 400 Pixel schmaler als tatsächlich benötigt (wenn die' DisplayWidth' 100 wäre). Es könnte also auch einen gegenteiligen Grund geben, die Breiten automatisch zu skalieren. – TLama