Uses OnBeforeDrawCell,
the most flexible event on TEgDBGridEx. Two things in one
handler: highlighting a value based on the data, and a column whose
content does not come from a field at all.
An orders grid with a Total field (can be negative for a
refund) and a DueDate field. Two requirements: a negative
Total should stand out in red and bold, and a Custom Cell
column (“Status”) should show “Late” or “On time” computed from
DueDate versus the current date - there is no such field in
the dataset.
Add a TColumn for the Status column at
design time with FieldName left empty - that is what makes
it a Custom Cell column (Assigned(Column.Field) is
False for it).
procedure TfrmOrders.GridBeforeDrawCell(Column: TColumn; var FontColor, BackColor: TColor;
Font: TFont; var CellText: string; var ImageIndex: Integer; var ImageAlignment: TAlignment);
begin
// Column.Field is nil for the Status column (empty FieldName) - always
// check before reading it, unlike a normal bound column.
if Column.FieldName = 'Total' then
begin
if Table.FieldByName('Total').AsFloat < 0 then
begin
FontColor := clRed;
Font.Style := Font.Style + [fsBold];
end;
end
else if Column.FieldName = 'Status' then
begin
if Table.FieldByName('DueDate').AsDateTime < Date then
CellText := 'Late'
else
CellText := 'On time';
end;
end;
Column.Field vs
Column.FieldName: the handler branches on
Column.FieldName (a plain string, always safe to read)
rather than on Column.Field (which would be
nil for the Custom Cell column and raise if dereferenced
without a check first).Font is the live Canvas.Font, not
a copy - `Font.Style := Font.Style
CellText arrives pre-filled with
Column.Field.DisplayText for a normal column, or
'' for a Custom Cell column - the Status
branch above replaces it unconditionally, which is the normal pattern
for a Custom Cell column since there is no default text to
preserve.Table.FieldByName(...) here is cheap for a couple of
fields, but avoid expensive lookups (e.g. a query to another table)
inside this handler if the grid repaints often; see OnGraphicError
for a case where the underlying work (image decoding) is already
unavoidably per-cell.FontColor/BackColor arrive already
resolved for selection and VCL Style - assigning
clRed here always overrides both, since custom colors set
through this event are not scoped by UseColorOnStyles/
UseFontColorOnStyles
the way Column.Color/Column.Font.Color are -
those two properties only arbitrate between a static column
color and the active theme, not a value this event assigns per row.The same signature is available as TEgColumn.OnBeforeDrawCell,
firing after the grid-level handler (if both are assigned). Useful to
keep a column’s own formatting logic attached to that column instead of
a single large grid-wide handler with a long if/else chain
by FieldName.