Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi DBGrid1.Columns[0].Width:= .... / geht das auch automatisch? (https://www.delphipraxis.net/209357-dbgrid1-columns%5B0%5D-width-%3D-geht-das-auch-automatisch.html)

NicoleWagner 25. Nov 2021 17:31

DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Mühsam lasse ich mein Programm immer wieder laufen und schreibe dann müüüühsam für jede Spalte extra die Breite fest:
DBGrid1.Columns[0].Width:=60;
DBGrid1.Columns[1].Width:=20;
DBGrid1.Columns[2].Width:=80;
usw. usw. usw.

Gibt es einen Weg, der die Spaltenbreite autoamtisch individuell der jeweiligen Textlänge anpasst?

Delphi.Narium 25. Nov 2021 17:57

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Ja, das geht, ungetestet ungefähr sowas:
Delphi-Quellcode:
// Im AfterOpen der Query, Table, ...
procedure TForm1.DatenbankomponentennameAfterOpen(DataSet: TDataSet);
var
  lb : TLabel;
  i : Integer;
begin
  lb := TLabel.Create(Self);
  lb.AutoSize := true;
  lb.ParentFont := true;
  // Wenn das DBGrid 'ne andere Schriftgröße hat, als das Formular:
  // lb.ParentFont := false;
  // lb.Font := DBGrid1.Font;
  // Damit werden die Spaltenbreiten an den Inhalt der ersten Zeile der Datenmenge angepasst.
  for i := 0 to DBGrid1.Columns.Count - 1 do begin
    lb.Caption := DBGrid1.Columns[i].Field.AsString;
    DBGrid1.Columns[i].Width := lb.Width;
  end;
  lb.Free;
end;
Alternative: Das DBGrid aus der JVCL nehmen, das bringt sowas und viele Vereinfachungen von Hause aus mit.

Der schöne Günther 26. Nov 2021 08:22

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Nur als Hinweis: Die Breite der Spalten kannst du auch bereits im Formular-Designer festlegen.

TiGü 26. Nov 2021 09:02

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Wäre das nicht einfacher über den Canvas zu lösen?

Delphi-Quellcode:
// Im AfterOpen der Query, Table, ...
procedure TForm1.DatenbankomponentennameAfterOpen(DataSet: TDataSet);
var
  i : Integer;
  LColumn: TColumn;
begin
  for i := 0 to DBGrid1.Columns.Count - 1 do
  begin
    LColumn := DBGrid1.Columns[i];
    LColumn.Width := DBGrid1.Canvas.TextWidth(LColumn.Field.AsString);
  end;
end;

Delphi.Narium 26. Nov 2021 10:15

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
@TiGü

jo, eindeutig ;-)
Soweit hab' ich halt mal wieder nicht gedacht.
Vorteil Deiner Version: Man muss sich nichtmal drum kümmern, ob die Schriftgröße, ... irgendwie passen.

Aber dann machen wir es noch ein bisserl kürzer ;-)
Delphi-Quellcode:
  for i := 0 to DBGrid1.Columns.Count - 1 do
  begin
    DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(DBGrid1.Columns[i].Field.AsString);
  end;

Uwe Raabe 26. Nov 2021 10:40

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Zitat:

Zitat von NicoleWagner (Beitrag 1498208)
Gibt es einen Weg, der die Spaltenbreite autoamtisch individuell der jeweiligen Textlänge anpasst?

Das Problem dabei ist, dass du das für jeden Datensatz machen und dann jeweils für jede Spalte den Maximalwert ermitteln müsstest. Das kann unter gewissen Bedingungen schon mal recht unperformant werden.

NicoleWagner 26. Nov 2021 11:16

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Danke für alle Antworten!

Nur jetzt bekomme ich Kopfschmerzen:
Leider funktionieren in meinem Fall beide Methoden nicht, auch wenn das Ergebnis gleich aussieht.
Siehe Screenshot.

Spannend ist die Spalte PL:
Sie ist überbreit. Sie WAR auch überbreit in der Query.
Denn es handelt sich um eine double Zahl, deren zahlreiche Kommastellen ich im Draw-Event auf 2 reduziere.
d.h. vielleicht ist die Spaltenbreite-Routine in einem Event, das zu früh ausgelöst wird.

nur, meine Kopfschmerzen:
Die Abfrage (siehe andere meiner Fragen)
i:=DataSource_TradesListen.DataSet.Fields.Count - 1;
wird erstmals korrekt bearbeitet. Und zwar im Draw Event!
Die Linie, die die Monate trennt, ist erstmal genau, wo sie sein soll.


Ich glaube, ich brauche eine Pause, weil nur mehr verwirrt.

Delphi.Narium 26. Nov 2021 11:44

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Naja, dann machen wir mal weiter und ergänzen die Routine:
Delphi-Quellcode:
  for i := 0 to DBGrid1.Columns.Count - 1 do
  begin
    case DBGrid1.Columns[i].Field.DataType of
      ftString, ftWideString :
      begin
        DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(DBGrid1.Columns[i].Field.AsString);
        DBGrid1.Columns[i].Alignment := taLeftJustify;
      end;
      ftSmallint, ftInteger, ftWord, ftAutoInc, ftLargeint :
      begin
        DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(Format('%6.0n',[DBGrid1.Columns[i].Field.AsFloat]));
        DBGrid1.Columns[i].Alignment := taRightJustify;
      end;
      ftFloat, ftCurrency :
      begin
        DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(Format('%6.2n',[DBGrid1.Columns[i].Field.AsFloat]));
        DBGrid1.Columns[i].Alignment := taRightJustify;
      end;
      ftDate :
      begin
        DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(FormatDateTime('dd.mm:yyyy', DBGrid1.Columns[i].Field.AsDateTime]));
        DBGrid1.Columns[i].Alignment := taLeftJustify;
      end;
      ftTime :
      begin
        DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(FormatDateTime('hh:nn:ss', DBGrid1.Columns[i].Field.AsDateTime]));
        DBGrid1.Columns[i].Alignment := taLeftJustify;
      end;
      ftDateTime :
      begin
        DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(FormatDateTime('dd.mm.yyyy hh:nn:ss', DBGrid1.Columns[i].Field.AsDateTime]));  
        DBGrid1.Columns[i].Alignment := taLeftJustify;
      end;
    else
      DBGrid1.Columns[i].Width := DBGrid1.Canvas.TextWidth(DBGrid1.Columns[i].Field.AsString);  
      DBGrid1.Columns[i].Alignment := taCenter;
    end;
  end;
Achso: Das ist jetzt einfach nur ungetestet hingedaddelt.
Bei den Format- bzw. FormatDateTimeaufrufen kannst Du die Formatstrings ja entsprechend Deinen Wünschen anpassen, ebenso die rechts- oder linksbündige Ausgabe ...

joachimd 26. Nov 2021 12:43

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
ich würde jetzt nicht unbedingt die Breite ermitteln, sondern nur eine maximale Breite setzen...
Code:
// Im AfterOpen der Query, Table, ...
procedure TForm1.DatenbankomponentennameAfterOpen(DataSet: TDataSet);
var
  LColumn: TColumn;
begin
  for LColumn in DBGrid1.Columns do
    LColumn.Width := min(LColumn.Width, 30);
end;

Jumpy 26. Nov 2021 12:43

AW: DBGrid1.Columns[0].Width:= .... / geht das auch automatisch?
 
Noch eine Version, die ich meine ich irgendwann mal hier im Forum bekommen habe (find es gerade nicht), ich meine von Sir Rufo. Hier in der Version analysiert es die ersten 40 Zeilen, um die optimale Spaltenbreite zu ermitteln:

Delphi-Quellcode:
procedure TProjekt.SetGridCol_Optimal(DBGrid: TDBGrid);
function TextGroesse(const Text : string; Font : TFont = nil) : TSize;
var
  DC : hDC;
  F : hFont;
begin
  F := 0;
  DC := GetDC(0);
  try
    if Font <> nil then F := SelectObject(DC, Font.Handle);
    if not GetTextExtentPoint32(DC, PChar(Text), Length(Text), Result) then
    begin
      Result.cx := 0;
      Result.cy := 0;
    end;
  finally
    if F <> 0 then SelectObject(DC, F);
    ReleaseDC(0, DC);
  end;
end;

var
  i, j : integer;
  iMaxRow : integer;
begin
  with DBGrid do
  begin
    // maximal XX Zeilen durchsuchen
    iMaxRow := Min(40, DataSource.DataSet.RecordCount);
    try
      DataSource.DataSet.DisableControls;
      Visible := false; // notwendig, da controls disabled!
      DataSource.DataSet.First;
      // mit Breite der Überschriften inizialisieren
      for i := 0 to Columns.Count - 1 do
      begin
        Columns.Items[i].Width := TextGroesse(Columns[i].Title.Caption, Font).cx + 10;
      end;
      // auf die größte Breite der ersten iMaxRow Zeilen stellen
      for j := 0 to iMaxRow - 1 do
      begin
        for i := 0 to Columns.Count - 1 do
        begin
          Columns.Items[i].Width := Max(TextGroesse(Fields[i].Text, Font).cx + 10, Columns.Items[i].Width);
        end;
        DataSource.DataSet.Next;
      end;
      DataSource.DataSet.First;
    finally
      DataSource.DataSet.EnableControls;
      Visible := true;
    end;
  end;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:15 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz