Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Spaltenbreite DBGrid automatisch anpassen (https://www.delphipraxis.net/158331-spaltenbreite-dbgrid-automatisch-anpassen.html)

DeddyH 14. Feb 2011 09:10

AW: Spaltenbreite DBGrid automatisch anpassen
 
Wenn Du mit MAX die Maximalbreite ermitteln kannst, kannst Du auch mit AVG die Durchschnittsbreite ermitteln ;). Multiplizierst Du das dann mit einem "breiten" Buchstaben wie dem angegebenen 'W' ist das zwar nicht der Weisheit letzter Schluss, aber IMO ein akzeptabler Kompromiss, wenn es nicht auf einzelne Pixel ankommt.

nahpets 14. Feb 2011 09:35

AW: Spaltenbreite DBGrid automatisch anpassen
 
Praktische Breite bei variabler Schrift ist
Code:
maximale Buchstabenanzahl
in W
* 75%
Damit bin ich in der Regel gut zurechtgekommen.

Bei Datum und Zahlen kann man ebenfalls die maximale Länge bestimmen und als Zeichen die 0 statt das W nehmen.

Sir Rufo 14. Feb 2011 10:35

AW: Spaltenbreite DBGrid automatisch anpassen
 
Hab ich mal von irgendwo aus dem Netz kopiert und noch etwas überarbeitet
Delphi-Quellcode:
unit uGridColumnWidth;

interface

uses
  DBGrids;

procedure SetGridColumnWidths( AGrid : TDBGrid );

implementation

uses
  DB, SysUtils;

procedure SetGridColumnWidths( AGrid : TDBGrid );
  const
    DEFBORDER = 10;
  var
    temp, idx, bcidx : integer;
    lmax : array of integer;
    bm : TBookmark;
  begin
    with AGrid do
      begin
        SetLength( lmax, Columns.Count );

        if dgTitles in AGrid.Options then
          begin

            // Measure Title

            Canvas.Font := AGrid.TitleFont;
            for idx := 0 to Columns.Count - 1 do
              if Columns[ idx ].Visible then
                lmax[ idx ] := Canvas.TextWidth( Columns[ idx ].Title.Caption )
                  + DEFBORDER;

          end;

        // Measure Data

        Canvas.Font := AGrid.Font;

        // Anzeige abschalten
        DataSource.DataSet.DisableControls;
        try
          // Aktuellen Datensatz merken
          bm := DataSource.DataSet.GetBookmark;
          // Zum ersten Datensatz springen
          DataSource.DataSet.First;
          // Alle Datensätze durchwandern
          while not DataSource.DataSet.EOF and ( DataSource.DataSet.RecNo < DataSource.DataSet.RecordCount ) do
            begin
              // Alle Spalten durchwandern
              for idx := 0 to Columns.Count - 1 do

                // Ist die Spalte sichtbar?
                if Columns[ idx ].Visible then
                  begin

                    // Breite des Inhalts ermitteln
                    temp := Canvas.TextWidth
                      ( trim( Columns[ idx ].Field.DisplayText ) ) + DEFBORDER;

                    // nur die maximale Breite merken
                    if temp > lmax[ idx ] then
                      lmax[ idx ] := temp;

                  end;

              // Nächster Datensatz
              DataSource.DataSet.Next;
            end;

          // Zum Datensatz zurückspringen, der eingangs gewählt war

          if DataSource.DataSet.BookmarkValid( bm ) then
            DataSource.DataSet.GotoBookmark( bm )
          else
            DataSource.DataSet.First;

        finally
          // Anzeige einschalten
          DataSource.DataSet.EnableControls;
        end;

        // Spaltenbreiten ändern

        for idx := 0 to Columns.Count - 1 do
          if Columns[ idx ].Visible then
            if lmax[ idx ] > 0 then
              Columns[ idx ].Width := lmax[ idx ];
      end;
  end; { SetGridColumnWidths }
end.

Jumpy 14. Feb 2011 11:24

AW: Spaltenbreite DBGrid automatisch anpassen
 
Danke. Das ist zwar die "Ich acker mal die ganze Datenmenge ab"-Variante, aber dafür cool gelöst (soweit ich das als Newbie beurteilen kann). Wenn ich mal Zeit hab (als Azubi hab ich die vllt.) mach ich mir den Spass und teste mal ab welcher Datenmenge es performanter wird, die Arbeit von der Datenbank erledigen zu lassen. Wobei die angezeigte Datenmenge im Grid in der Regel so klein ist, dass obiges bestimmt schneller ist.
Wer sich dagegen 12 Millionen Datensätz im Grid anzeigen läßt ist selber Schuld.:-D

Bummi 14. Feb 2011 11:31

AW: Spaltenbreite DBGrid automatisch anpassen
 
als gäbe noch die Q&D Option zu Laufzeit im OnPaint über Canvas.TextWidth die Spalten zu vergrößern, sofern sie zu schmal sind.
Delphi-Quellcode:
   if DBGrid1.Canvas.TextWidth(Column.Field.AsString) > (Rect.Right - Rect.Left) then
    begin
    Column.Width := DBGrid1.Canvas.TextWidth(Column.Field.AsString);
    end;

DeddyH 15. Feb 2011 07:46

AW: Spaltenbreite DBGrid automatisch anpassen
 
Das könnte aber unschöne Effekte beim Scrollen zur Folge haben.

Bummi 15. Feb 2011 08:58

AW: Spaltenbreite DBGrid automatisch anpassen
 
Zitat:

Das könnte aber unschöne Effekte beim Scrollen zur Folge haben.
Die Spalten werden breiter wenn nötig, eine gewisse Dynamik ist gegeben, das ist richtig.

David Martens 15. Feb 2011 14:01

AW: Spaltenbreite DBGrid automatisch anpassen
 
Also wir haben das so gelöst:
Delphi-Quellcode:
function TextGroesse(const Text : string; Font : TFont = nil) : TSize;
var
  DC : hDC;
  F : hFont;
  R : TRect;
begin
  F := 0;
  DC := GetDC(0);
  try
    if Font <> nil then
      F := SelectObject(DC, Font.Handle);
    if not GetTextExtentPoint32(DC, 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;

procedure SetColumnWidth(DBGrid : TDBGrid);
var
  i, j : integer;
  iMaxRow : integer;
begin
  with DBGrid do
  begin
    //     maximal || 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, Canvas.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, Canvas.Font).cx + 10, Columns.Items[i].Width);
        end;

        DataSource.DataSet.Next;
      end;
      DataSource.DataSet.First;
    finally
      DataSource.DataSet.EnableControls;
      Visible := true;
    end;
  end;
end;
Leider mussten wir GetTextExtentPoint32 für die Textbreite verwenden, da Canvas.TextWidth manchmal einen fehlerhaften (zu kleinen) Wert liefert.

Bemerkungen:
1. Da wir z.T. sehr viele Datensätze haben können > 10 Mio. haben wir die Breitenberechnung auf 40 DS beschränkt.
2. An die Textbreite wird + 10 angehängt um einen kleinen Abstand zur Begrenzung zu haben.
3. Wir haben auf Bookmarks verzichtet, da die Berechnung der Breite nur beim inizialen Laden der Daten notwenig ist.
4. Besonders wichtig sind DisableControls und Visible := false, damit wird die Funktion um ein vielfaches schneller.

Gruß David

mkinzler 15. Feb 2011 16:26

AW: Spaltenbreite DBGrid automatisch anpassen
 
Man könnte auch den Canvas fragen, wie viele Pixel der Text gerendert hat.

nahpets 16. Feb 2011 07:08

AW: Spaltenbreite DBGrid automatisch anpassen
 
Hallo,

oder mal das TJVDBGrid von den Jedis anschauen, es hat ein Attribut für maximale Spaltebreite, für minimale Spaltenbereite, kann, wenn ich das richtig sehe, auch die Spaltenbreite automatisch auf das richtige Maß bringen.

Könnte von daher eine Alternative zum "Selbermachen" sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:41 Uhr.
Seite 2 von 3     12 3      

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