Wie in der kurzen Beschreibung vom 05.05.2017 geht es in diesem Artikel auch um die Ergänzung von Delphis DBGrid. Eines der Features, die man bei der Nutzung des DBGrids vermissen kann, ist die automatische Anpassung der Spaltenbreiten auf Knopfdruck. In diesem Beispiel wird eine Lösungsvariante für diese Aufgabenstellung vorgestellt und demonstriert, wie der entsprechende Code mit dem aus „Spaltensortierung mit DBGrid“ gemeinsam ohne Konflikte genutzt werden kann.
Wie für die Sortierfunktionalität gilt auch hier, dass der folgende Weg nur eine von vielen Möglichkeiten darstellt und je nach Anforderungen die Lösungen anders aussehen können. Das folgende Beispiel ist mit Delphi XE5 geschrieben worden und nutzen die FireDAC-Komponenten.
Folgende Komponenten wurden hier auf dem Formular platziert:
- TDBGrid
- TDBNavigator
- TFDConnector
- TDataSource
- TFDQuery
- TFDGUIxWaitCursor und TFDPhysMySQLDriverLink
TFDGUIxWaitCursor und TFDPhysMySQLDriverLink sind hier für FireDAC notwendig, da eine MySQL-Datenbank genutzt wird und können für alles Weitere ignoriert werden.
In der TFDConnection-Komponente wird die Verbindung zum Server eingerichtet. Das TDBGrid und der TDBNavigator werden mit der TDatasource und diese mit der TFDQuery verknüpft, die wiederum mit der TFDConnection verbunden ist.
Die TFDQuery enthält ein sehr schlichtes Statement für den Zugriff auf die Testdatenbank:
SELECT * FROM Artikel |
Um eine Spalte automatisch an die breite seiner breitesten Zelle anzupassen, wird das OnTitleClick-Event des DBGrids genutzt. Der Code, der bei dem Event ausgeführt wird, kann nun so aussehen:
procedure TForm1.DBGrid1TitleClick(Column: TColumn); var i: integer; TmpRecNo: Integer; NewColumnWidth: Integer; ColumnTitleWidth: Integer; ColumnCellWidth: Integer; ColTitleAdd: Integer; ColCellAdd: Integer; ColTitleMult: Real; ColCellMult: Real; begin //Festlegen der Modifikatoren für zusätzliche Anpassung der Spaltenbreite //Spaltenbreite = Round(Basiswert * Multiplikator) + Summand ColTitleAdd := 0; ColTitleMult := 1.10; ColCellAdd := 0; ColCellMult := 1.10; //Anpassung der Spaltenbreite ColumnTitleWidth := Round(DBGrid1.Canvas.TextExtent(Column.Title.Caption).cx * ColTitleMult) + ColTitleAdd; ColumnCellWidth := Round(DBGrid1.Canvas.TextExtent(Column.Field.DisplayText).cx * ColCellMult) + ColCellAdd; * ColCellMult) + ColCellAdd; //Die breiteste Zelle finden TmpRecNo := FDQuery1.RecNo; FDQuery1.First; FDQuery1.DisableControls; For i := 0 to FDQuery1.RecordCount - 1 do begin If ColumnCellWidth < Round(DBGrid1.Canvas.TextExtent(Column.Field.DisplayText).cx * ColTitleMult) + ColTitleAdd then ColumnCellWidth := Round(DBGrid1.Canvas.TextExtent(Column.Field.DisplayText).cx * ColCellMult) + ColCellAdd; FDQuery1.Next; end; FDQuery1.RecNo := TmpRecNo; FDQuery1.EnableControls; //Falls der Titel breiter ist, als die breiteste Zeile, an diesem orientieren If ColumnTitleWidth > ColumnCellWidth then NewColumnWidth := ColumnTitleWidth Else NewColumnWidth := ColumnCellWidth; Column.Width := NewColumnWidth; end; |
Mit dieser Einrichtung des Codes wird er nun bei einem einfachen Mausklick auf einem Titelfeld des DBGrids ausgeführt. Damit dieser allerdings nur bei einem Doppelklick ausgelöst wird und kompatibel mit dem Sortiercode aus dem Artikel „Spaltensortierung im DBGrid“ ist, müssen noch ein paar Ergänzungen vorgenommen werden.
Wiese man einfach den Code für die Spaltenbreite dem OnDblClick-Event des DBGrids zu, würde mit jedem Doppelklick auch das OnTitleClick-Event, also der Sortiercode, zweimal ausgeführt werden. Um dieses Problem zu lösen, wird für beide Funktionalitäten das OnTitle-Click-Event ausgewählt und ein Doppelklick unabhängig von den Vorgaben des DBGrids definiert.
Um das zu erreichen wird zusätzlich eine TTimer-Komponente auf dem Formular benötigt. Außerdem müssen zwei globale Variablen definiert werden, die für die Übergaben zwischen der OnTitleClick- und der Timer-Prozedur erforderlich sind. In diesem Beispiel sehen diese Variablen so aus:
private SingleClick: boolean = true; SelectedColumn: TColumn; |
Ist der TTimer auf dem Formular platziert, muss er mit dem Umstellen seiner Eigenschaft „Enabled“ auf „False“ deaktiviert werden. Mit Hilfe seiner „Interval“-Eigenschaft kann gesteuert werden, wie schnell geklickt werden muss, damit das Programm einen Doppelklick registriert. In diesem Beispiel wird ein Interval von 200 gewählt. Nun müssen dem OnTimer-Event noch folgende Zeilen hinzugefügt werden:
procedure TForm1.Timer1Timer(Sender: TObject); begin SingleClick := true; Timer1.Enabled := false; DBGrid1TitleClick(SelectedColumn); end; |
Der kombinierte Code aus dem Artikel vom 05.05.2017 und der Spaltensortierung mit Berücksichtigung der Doppelklickproblematik kann nun so aussehen:
procedure TForm1.DBGrid1TitleClick(Column: TColumn); |