Here's
a handy method to automatically fix the size of TDBGrid columns (at
run-time) to fit the DBGrid width (remove the unfilled space at the
right edge of the grid; and consequently remove the horizontal scroll
bar) when the user resizes the container containing the grid.
Designed to enable a user to view and edit data in a tabular grid, the DBGrid provides various ways of customizing the way it represents "its" data. I've already written a dozens of articles and tips that enable you to extend the functionality of the TDBGrid component to the Max.
With so flexible component, a Delphi developer can always find new ways to make it more powerful - this article provides one handy customization.
The Problem:
One of the missing features of TDBGrid is that there is no option to automatically adjust the widths of specific columns to completely fit the grid's client width.
When the user resizes the DBGrid component at run-time the column widths are not resized. Thus, if the width of the DBGrid is larger than the total width of all the columns, you'll get an empty area right after the last column. On the other hand, if the total width of all the columns is larger than the width of the DBGrid a horizontal scroll bar will appear.

Designed to enable a user to view and edit data in a tabular grid, the DBGrid provides various ways of customizing the way it represents "its" data. I've already written a dozens of articles and tips that enable you to extend the functionality of the TDBGrid component to the Max.
With so flexible component, a Delphi developer can always find new ways to make it more powerful - this article provides one handy customization.
The Problem:
One of the missing features of TDBGrid is that there is no option to automatically adjust the widths of specific columns to completely fit the grid's client width.
When the user resizes the DBGrid component at run-time the column widths are not resized. Thus, if the width of the DBGrid is larger than the total width of all the columns, you'll get an empty area right after the last column. On the other hand, if the total width of all the columns is larger than the width of the DBGrid a horizontal scroll bar will appear.
The Solution
In this article I'll present you with one handy procedure that fixes the widths of selective DBGrid columns when the grid is resized at run-time.
In this article I'll present you with one handy procedure that fixes the widths of selective DBGrid columns when the grid is resized at run-time.
While writing code for my solution to the "problem", I was guided
with the fact that in most cases (in my experience) only two-three
columns in a DBGrid actually need to be auto-resized; all the other
columns display some "static-width" data. For example, you can always
specify fixed width for columns displaying values from data fields that
are represented with TDateTimeField, TFloatField, TIntegerField and
similar. What's more, you'll probably create (at design-time) persistent
field components using the Fields editor, to specifies the fields in
the dataset, their properties, and their ordering. Having a TField
descendant object, you can use the Tag property to indicate that a
particular column displaying values for that field must be auto-sized.
This is the idea: if we want a column to auto-fit available space, assign an integer value for the TField descendant's Tag property that indicates the corresponding column's minimum width.
Here's the code:
This is the idea: if we want a column to auto-fit available space, assign an integer value for the TField descendant's Tag property that indicates the corresponding column's minimum width.
Here's the code:
"Smart" columns and the FixDBGridColumnsWidth procedure
First, in the OnCreate event for the Form object containing the DBGrid,
specify what columns need to be auto-resized by assigning a non-zero
value for the Tag property of the corresponding TField object.
procedure TForm1.FormCreate(Sender: TObject); begin //setup autoresizable columns by asigning //Minimm Width in the Tag property. //using fixed value: 40 px Table1.FieldByName('FirstName').Tag := 40; //using variable value: width of the //default Column title text Table1.FieldByName('LastName').Tag := 4 + Canvas.TextWidth( Table1.FieldByName('LastName').DisplayName); end; |
In the above code, Table1 is a TTable component linked to a DataSource
component which is linked with the DBGrid. The Table1.Table property
points to the DBDemos Employee table.
We have marked the columns displaying the values for FirstName and LastName fields to be auto-resizable.
Next, call our FixDBGridColumnsWidth in the OnResize event handler for the Form:
We have marked the columns displaying the values for FirstName and LastName fields to be auto-resizable.
Next, call our FixDBGridColumnsWidth in the OnResize event handler for the Form:
procedure TForm1.FormResize(Sender: TObject); begin FixDBGridColumnsWidth(DBGrid1); end; |
Finally, here's the FixDBGridColumnsWidth procedure's code:
procedure FixDBGridColumnsWidth(const DBGrid: TDBGrid); var i : integer; TotWidth : integer; VarWidth : integer; ResizableColumnCount : integer; AColumn : TColumn; begin //total width of all columns before resize TotWidth := 0; //how to divide any extra space in the grid VarWidth := 0; //how many columns need to be auto-resized ResizableColumnCount := 0; for i := 0 to -1 + DBGrid.Columns.Count do begin TotWidth := TotWidth + DBGrid.Columns[i].Width; if DBGrid.Columns[i].Field.Tag <> 0 then Inc(ResizableColumnCount); end; //add 1px for the column separator line if dgColLines in DBGrid.Options then TotWidth := TotWidth + DBGrid.Columns.Count; //add indicator column width if dgIndicator in DBGrid.Options then TotWidth := TotWidth + IndicatorWidth; //width vale "left" VarWidth := DBGrid.ClientWidth - TotWidth; //Equally distribute VarWidth //to all auto-resizable columns if ResizableColumnCount > 0 then VarWidth := varWidth div ResizableColumnCount; for i := 0 to -1 + DBGrid.Columns.Count do begin AColumn := DBGrid.Columns[i]; if AColumn.Field.Tag <> 0 then begin AColumn.Width := AColumn.Width + VarWidth; if AColumn.Width < AColumn.Field.Tag then AColumn.Width := AColumn.Field.Tag; end; end; end; (*FixDBGridColumnsWidth*) |
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου