HowToUseGrids topic
How to use
Grids including
StringGrids,
DrawGrids and
DbGrids.
Declaration
HowToUseGridsDescription
Customizing Grids
Grids are components derived from the TCustomControl class and do
not have a native widget associated with them. So they are not restricted by
the look of the current interface theme. This can be both an advantage and a
disadvantage: usually programmers want to create a uniform-look application.
Lazarus grids are flexible enough to allow programmers to make them look
similar to other native controls; alternatively they can customize the grid
to obtain almost the same look in any platform or widget interface (with the
exception of scroll bars, whose look is still determined by the current
theme).
Some properties can affect the way the grid looks by acting when the cell is
about to be painted in PrepareCanvas/OnPrepareCanvas by changing
default canvas properties like brush color or font. Following is a list of
such properties:
| Property | Meaning |
|---|---|
| AlternateColor | The user can change the background color that appears on alternate rows. This is to allow easy reading of grid rows data. |
| Color | Sets the primary color used to draw non fixed cells' background. |
| FixedColor | The color used to draw fixed cells' background. |
| Flat | Eliminates the 3d look of fixed cells. |
| TitleFont | Font used to draw the text in fixed cells. |
| TitleStyle |
Changes the 3D look of fixed cells. There are 3 settings:
|
| AltColorStartNormal | If True, alternate color is always in the second row after fixed rows; the first row after fixed rows will always be the default color. If False, default color is set to the first row as if there were no fixed rows. |
| BorderColor | Sets the grid's border color used when Flat=True and
BorderStyle is bsSingle.
|
| EditorBorderStyle | If set to bsNone under Windows the cell editors will not have the
border, like in Delphi; set to bsSingle by default because the
border can be theme specific in some widgetsets and to allow a uniform look.
|
| FocusColor | The color used to draw the current focused cell if UseXORFeatures
is not set; by default this is clRed.
|
| FocusRectVisible | Turns on/off the drawing of focused cell. |
| GridLineColor | Color of grid lines in non fixed area. |
| GridLineStyle | Pen style used to draw lines in non fixed area, possible choices are:
psSolid, psDash, psDot,
psDashDot, psDashDotDot, psinsideFrame,
psPattern, psClear; default is psSolid.
|
| SelectedColor | Color used to draw cell background on selected cells. |
| UseXORFeatures | If set, focus rect is drawn using XOR mode so it should make visible the focus rect in combination with any cell color background. It also affects the way that moving columns look |
| DefaultDrawing | Normally the grid prepares its grid canvas using properties according to the
kind of cell that is being painted. If the user has written an
OnDrawCell event handler, it is used to perform specified drawing
operations for a given cell. DefaultDrawing (if set) also paints
the cell background; if the user is taking full responsibility for drawing
the cell it is better to turn off this so painting is not duplicated. In a
StringGrid, if DefaultDrawing is set it draws the text in each cell.
|
| AutoAdvance | Where the cell cursor will go when pressing enter or tab/shift tab, or after editing. |
| ExtendedColSizing | If True, the user can resize columns, not just at the headers, but anywhere along the column's height. |
Other Properties that Affect Grid Appearance:
Options
This is a set of zero or more choices, with some elements that enable diverse functionality but others that are related directly with grid's look. Options can be set at design-time or run-time.
-
goFixedVertLine, goFixedHorzLine - Draws a vertical or horizontal line respectively, delimiting cells or columns in the fixed area; active by default.
-
goVertLine, goHorzLine - The same as previous, but for the normal browsable area. A grid can be made to simulate the visual appearance of a list box by removing both of these options.
-
goDrawFocusSelected - If this option is enabled, a selection background is painted in the focused
cell in addition to the focused dotted rectangle. Please note: this doesn't
work when the
goRowSelectoption is set; in such case the row is always painted as ifgoDrawFocusSelectedis set. -
goRowSelect - Selects the full row instead of individual cells.
-
goFixedRowNumbering - If set, grid will do numbering of rows in first fixed column.
-
goHeaderHotTracking - If set, the grid will try to show a different look when the mouse cursor is
over any fixed cell. In order for this to work, desired cell zone needs to
be enabled with the
HeaderHotZones. Try combining this option withTitleStyle=tsNativeto get themed hot tracking look. -
goHeaderPushedLook - If set, this option enables a pushed look when clicking any fixed cell. The
zone of "pushable" cells is enabled using
HeaderPushedZonesproperty.
Description of the Grid Drawing Process
Like other custom controls, the grid is drawn using the paint method. In general terms the grid is drawn by painting all rows, and each row by painting its individual cells. The process is as follows:
- First, the visible cells area is determined: each row is tested to see if it intersects the canvas clipping region; if it's OK, then the visible area is painted by drawing columns of each row.
- The column and row values are used to identify the cell that is about to be painted and again each column is tested for intersection with the clipping region; if everything is OK, some additional properties like the cell's rectangular extent and visual state are passed as arguments to the DrawCell method.
-
As the drawing process is running, the visual state of each cell is adjusted according to grid options and position within grid. The visual state is retained in a variable of type
TGridDrawStatewhich is a set with following elements:gdSelected The cell will have a selected look. gdFocused The cell will have a focused look. gdFixed Cell have to be painted with fixed cell look. gdHot the mouse is over this cell, so paint it with hot tracking look gdPushed the cell is being clicked, paint it with pushed look -
DrawCell- The DrawCell method is virtual and may be overridden in descendent grids to do custom drawing. The information passed toDrawCellhelps to identify which particular cell is being painted, the physical area occupied on the screen and its visible status. See DrawCell reference for details. For each cell the following occurs:- PrepareCanvas - If DefaultDrawing is True, the grid canvas is setup with default properties for brush and font based on current visual state. For several design and run-time properties, the text alignment is set to match programmer selection in custom columns if they exists. If DefaultDrawing is False, brush color is set to clWindow and Font color to clWindowText, the text alignment is set to the DefaultTextStyle value.
-
OnPrepareCanvas - If the programmer wrote an event handler for the
OnPrepareCanvasevent, it is called at this point. This event can be used for doing simple customization like changing a cell's background color, font's properties like color, font face and style, Text layout like different combinations of left, center, top, bottom, right alignment, etc. Any change made to the canvas for a particular cell in this event would be lost, because the next cell drawing will reset canvas again to a default state. So it's safe doing changes only for a particular cell or cells and forget about it for the rest. Using this event sometimes helps to avoid using theOnDrawCellgrid event, where users would be forced to duplicate the grid's drawing code. -
OnDrawCell - Next, if no handler for the
OnDrawCellevent was specified, the grid calls theDefaultDrawCellmethod which simply paints the cell background using the current canvas brush color and style. If theOnDrawCellhandler exists, the grid first paints the cell background, but only if theDefaultDrawingwas set; then it calls theOnDrawCellevent to do custom cell painting. Usually programmers want to do custom drawing only for particular cells, but standard drawing for others: in this case, they can restrict custom operation to certain cell or cells by looking intoACol, ARowandAStatearguments, and for other cells simply call theDefaultDrawCellmethod and let the grid to take care of it. -
Text - At this point, if the
DefaultDrawingis True, the cell's text content is painted (only forTStringGrid). -
Grid lines - The last step for each cell is to paint the grid lines:
if grid options
goVertLine, goHorzLine, goFixedVertLineandgoFixedHorzLineare specified the cell grid is drawn at this point. Grids with only rows or only cols can be obtained by changing these options. If the programmer elected to have a "themed" look it is done at this point also (see TitleStyle). -
FocusRect - When all columns of the current row have been painted it
is time to draw the focus rectangle for the current selected cell or for the
whole row if the
goRowSelectoption is set.
Grid Cell Selection
The location of a grid's current (focused) cell (or row) can be changed
using keyboard, mouse or through code. In order to change cell focus
successfully to another position, we must test the target position to see if
it is allowed to receive cell focus. When using the keyboard,
AutoAdvance performs part of the process by finding what should
be the next focused cell. When using mouse clicks or moving by code, focus
will not move from the current cell unless the target cell is permitted to
receive focus.
The grid calls SelectCell to see if a cell can be focused: if
this function returns True, then the target cell identified with
arguments aCol and aRow can be focused (the current
implementation of TCustomGrid simply returns True).
TCustomDrawGrid and hence TDrawGrid and
TStringGrid override this method and check first if a cell is any
wider than 0; normally you don't want a 0 width cell selected so a cell with
this characteristics is skipped automatically in the process of finding a
suitable cell. The overridden method SelectCell also calls the
user configurable event OnSelectCell: this event receives the
cell coordinates as arguments and always returns a default result of
True.
If a cell can be focused and we are sure a movement will take place, the
method BeforeMoveSelection is called; this in turns triggers the
OnBeforeSelection event. This method's arguments are the
coordinates for the new focused cell; at this point any visible editor is
hidden too. The "before" word means that selection is not yet changed and
current focused coordinates can be accessed with grid.Col and
grid.Row properties.
After that, the internal focused cell coordinates are changed and
MoveSelection is called; this method's purpose (if set) is to
trigger the OnSelection event (this is a notification that the
focused cell has changed and the new cell coordinates are available through
grid.row and grid.col properties).
Note that is not good to use the OnSelectCell event to detect cell
focus changes, as this event will be triggered several times even for the
same cell in the process of finding a suitable cell. Is better to use
OnBeforeSelection or OnSelection events for this
purpose.
Using Cell Editors
Users can specify what editor will be used for a cell using one of two methods.
-
Using a custom column and selecting the ButtonStyle of the column. In
this method the user can select the style of the editor that will be shown.
Available values are:
cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn. -
Using the OnSelectEditor Grid Event
Here the user specifies in the
Editorparameter which editor to use for a cell identified byaCol,ARowin aTCustomDrawGridderived grid orTColumninTCustomDBGrid. The publicEditorByStyle()function takes as parameter one of the following values:cbsAuto, cbsEllipsis, cbsNone, cbsPickList, cbsCheckboxColumn.This method takes precedence over the first one using custom columns. A Custom cell editor can be specified here, with values specific to the cell, row or column.
Description of Editor Styles
The following is a description of the editor styles. They are enumerated
values of type TColumnButtonStyle and so they are prefixed by
'cbs'. This type was used to remain compatible with Delphi's
DBGrid.
- cbsAuto - This is the default editor style for TCustomGrid derived grids. The TStringCellEditor derived from TCustomMaskEdit is specialized to edit single line strings and is used by default in TStringGrid and TDrawGrid. When using Custom Columns, if the programmer filled the Column's PickList property, this behaves as if cbsPickList editor style was set. For a TCustomDBGrid that has a field of type Boolean, it behaves as if cbsCheckBoxColumn editor style was specified. This is the recommended value for custom cell editors.
-
cbsEllipsis - This editor style is the most generic one. A button with ellipsis (...) appears in the editing cell and the programmer can use the OnEditButtonClick grid event to take any programmed action when the user presses the button. For example a calendar dialog could pop up to allow the user to select a specific date, a file open dialog could appear to find files, or a calculator could appear so the user could enter the numeric result of calculations, etc.
- OnEditButtonClick is just a notification, to find out in which cell a button has been clicked by taking a look at the grid.Row and grid.Col properties.
- A DBGrid has specific properties to retrieve the active column or field and because this event occurs in the active record, it could update the information in the active field.
- This editor style is implemented using TButtonCellEditor, a direct descendant of TButton.
- cbsNone - This editor style instructs the grid not to use any editor for a specific column; it behaves as if the cell were read-only.
-
cbsPickList - Used to present the user with a list of values that can be entered. This editor style is implemented using TPickListCellEditor, a component derived from TCustomComboBox. The list of values that are shown is filled in one of two ways depending on the method used to select the editor style.
When using custom columns, programmers can enter a list of values using the PickList property for the column.
-
cbsCheckboxColumn - This editor style is at the moment only available in TDBGrid. If a field's contents associated with the column are restricted to a pair of values, for example, yes-no, True-false, on-off, 1-0, etc. then cbsCheckboxColumn is used to modify the appearance of a column by using a check box representation that the user can toggle by using a mouse click or pressing the SPACE key.
- If a ButtonStyle for a column is set to cbsAuto and DBGrid detects that the field associated with the column is a Boolean field, then the grid uses this editor style automatically. This automatic selection can be disabled or enabled using the DBGrid OptionsExtra property; setting dgeCheckboxColumn element to False disables this feature.
- The values that are used to recognize the checked or unchecked states are set in a column's properties ValueChecked and ValueUnchecked.
- At any moment, the field value can be in one of three states: Unchecked, Checked or Grayed.
An experiment, built from development snapshots. Not the official Free Pascal or Lazarus documentation.
