Sonntag, 7. September 2008

entwickler.com Magazine Konferenzen Akademie Entwickler-Forum Jobbörse Bücher
Software & Support Verlag

TDBGrid mit dynamischer Spaltenbreite

Frage:Wie kann man die Spaltenbreite im TDBGrid so einstellen, dass sie sich automatisch der größten Breite des Textes anpasst?

Antwort: Diese Frage besteht bei genauerer Betrachtung aus gleich zwei Teilen:
1. Wie ermittele ich die maximale Zeichenanzahl der in der anzuzeigenden Tabellenspalte vorgefundenen Werte?
2. Wie kann ich zur Laufzeit die Spaltenbreite im TDBGrid anpassen?

Für die erste Aufgabe gibt es verschiedene Wege. Die Anwendung könnte sofort nach dem Öffnen der Datenmenge in einer Schleife alle Datensätze durchgehen, um zuerst den maximalen Wert zu suchen, um dann einmalig die Spaltenbreite anzupassen. Um diesen Aufwand zu vermeiden, kann die aber erst später über das TDBGrid-Ereigenis OnDrawColumnCell nachgeholt werden, auch wenn dann die Spaltenbreite zur Laufzeit mehrfach geändert wird, wenn es in der Spaltenbreite sehr große Unterschiede gibt. Denn immer dann, wenn dieses Ereignis eintrifft, kann das eigene Programm über den Konstrukt TDBGrid(Sender).Canvas.TextExtent(Column.Field.DisplayText).cx nachfragen, welcher Platz für die vollständige Darstellung benötigt würde. Vergleich man diesen Wert mit dem Parameter Column.Width, so kann das Programm erkennen, wenn die aktuelle Spaltenbreite nicht ausreicht. In diesem Fall schickt sich das Formular selbst eine private Botschaft, um die betroffene Spalte im TDBGrid entsprechend zu verbreitern. Da eine über die Win32-API-Funktion PostMessage verschickte Nachricht über die Botschaftswarteschlange erst dann ausgelesen wird, wenn die Anwendung nichts besseres zu tun hat, kommt diese Manipulation dem interen Ablauf im TDBGrid nicht in die Quere.

Das folgende Beispiel demonstriert dies:

{ ****************************************************************
  Autor            :  Andreas Kosch
  Compiler         :  Delphi 6.0 Enterprise
  Betriebssystem   :  Windows 2000 SP2
  Erstellt am      :  07.08.2001
  Beschreibung     :  Spaltenbreite im TDBGrid zur Laufzeit
                      automatisch an den längen Spaltenwert
                      anpassen, der angezeigt werden muss.
 **************************************************************** }

unit DBGridAutoSizeFrm;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Grids, DBGrids, DB, DBTables, StdCtrls;
const PM_COLUMNWIDTH = WM_APP + 1;
type TForm1 = class(TForm) Table1: TTable; DataSource1: TDataSource; DBGrid1: TDBGrid; procedure DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); procedure FormCreate(Sender: TObject); private { Private-Deklarationen } procedure PMCOLUMNWIDTH(var Msg: TMessage); message PM_COLUMNWIDTH; public { Public-Deklarationen } end;
var Form1: TForm1;
implementation
{ *.dfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject); var i : Integer; begin with Table1 do for i := 0 to Pred(Fields.Count) do Fields[i].DisplayWidth := 4; end;
procedure TForm1.PMCOLUMNWIDTH(var Msg: TMessage); begin with TColumn(Pointer(Msg.LParam)) do Width := Msg.WParam; end;
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState); begin with TDBGrid(Sender).Canvas.TextExtent(Column.Field.DisplayText) do if (cx + 6 > Column.Width) then Postmessage(Handle, PM_COLUMNWIDTH, cx + 10, LongInt(Column)); end;
end.






Software & Support Verlag GmbH