Autofill
Excel-style fill handle — the user selects a range, drags the small square at the bottom-right, and the grid extrapolates the values. Built-in sequence detection covers numbers, dates, days, months, and custom lists.
Overview
Two pieces:
- Enable the fill handle via
Options.Selection.AutoFill. - (Optional) Register custom lists or override the value calculation.
Built-in detection covers numeric sequences (1, 2, 3, 10, 20, 30), date
sequences (daily, weekly, monthly, yearly increments), weekday and month names,
and any list registered via AutoFillCustomListSet.
Options.Selection.Mode must be gsmCellRange for autofill to work.
Quick example
procedure TForm1.FormCreate(Sender: TObject);
begin
// Show the AutoFill handle on the active selection
Grid.Options.Selection.Mode := gsmCellRange;
Grid.Options.Selection.AutoFill := True;
// Register custom lists that AutoFill recognises and cycles through
Grid.AutoFillCustomListSet('StatusList',
['TODO', 'In Progress', 'Review', 'Done']);
Grid.AutoFillCustomListSet('PriorityList',
['Low', 'Medium', 'High', 'Critical']);
Grid.AutoFillCustomListSet('QuarterList',
['Q1', 'Q2', 'Q3', 'Q4']);
// Hook the calculation event for cases the built-in detector cannot handle.
Grid.OnAutoFillCalculateValue := AutoFillCalculate;
end;
procedure TForm1.AutoFillCalculate(Sender: TObject;
SourceCells: TTMSFNCDataGridCellCoordRange;
SourceValues: TTMSFNCDataGridDataValues;
TargetCells: TTMSFNCDataGridCellCoordRange;
FillIndex: Integer;
Direction: TTMSFNCDataGridDataAutoFillDirection;
var NewValue: TTMSFNCDataGridCellValue;
var Handled: Boolean);
begin
// Example: continue a sequence of single lowercase letters (a, b -> c, d, ...)
if (Length(SourceValues) >= 2) then
begin
NewValue := Char(Ord('a') + FillIndex mod 26);
Handled := True;
end;
end;
Step by step
1. Enable
Grid.Options.Selection.Mode := gsmCellRange;
Grid.Options.Selection.AutoFill := True;
The fill handle appears at the bottom-right corner of the selection. A mouse drag extends the fill in any direction.
2. Programmatic fill
Grid.AutoFill(
MakeCell(0, 1), MakeCell(0, 2), // source range (rows 1–2)
MakeCell(0, 1), MakeCell(0, 19) // target range (fill rows 1–19)
);
3. Register custom lists
Grid.AutoFillCustomListSet('StatusList',
['TODO', 'In Progress', 'Review', 'Done']);
When the user drags from a cell containing one of those strings, the grid cycles through the list.
4. Override the calculation
For domain logic that built-in extrapolation doesn't cover, hook
OnAutoFillCalculateValue:
procedure TForm1.AutoFillCalc(Sender: TObject;
SourceCells: TTMSFNCDataGridCellCoordRange;
SourceValues: TTMSFNCDataGridDataValues;
TargetCells: TTMSFNCDataGridCellCoordRange;
FillIndex: Integer;
Direction: TTMSFNCDataGridDataAutoFillDirection;
var NewValue: TTMSFNCDataGridCellValue;
var Handled: Boolean);
begin
// compute NewValue from SourceValues and FillIndex
Handled := True;
end;
FillIndex is 0-based for each cell to fill. Direction is gafdDown,
gafdUp, gafdLeft, or gafdRight.
5. Provide a custom list dynamically
If the list items come from a database rather than being pre-registered, hook
OnAutoFillGetCustomList:
procedure TForm1.AutoFillGetCustomList(Sender: TObject; BaseValue: string;
var Values: TArray<string>; var Handled: Boolean);
begin
if BaseValue.StartsWith('Q') then
begin
Values := ['Q1', 'Q2', 'Q3', 'Q4'];
Handled := True;
end;
end;
Shrinking the fill range
The fill handle works in both directions. After the user drags it outward to extend the fill, dragging it back inward — over or inside the original selection — retracts the fill, and the grid clears the cells the handle moves back over. This makes the handle a single gesture for both "fill these cells" and "undo that fill": overshoot and pull back, and the extra cells are emptied rather than left holding stale extrapolated values.
This behaviour is automatic whenever Options.Selection.AutoFill is enabled —
there is no separate option to switch it on. The retract clears only the cells
beyond the original selection that the previous outward drag had filled; the
source selection itself is left untouched.
Combining autofill with a custom list and visual customisation
This example registers a day-name custom list, enables autofill on a cell-range selection, and changes the fill-handle appearance — a typical production setup where autofill replaces a data-entry repetition task:
procedure TForm1.FormCreate(Sender: TObject);
begin
// Register a custom cyclic list (Step by step — custom lists)
Grid.AutoFillCustomListSet('Days',
TArray<string>.Create('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'));
// Require cell-range selection so the fill handle appears
Grid.Options.Selection.Mode := gsmCellRange;
Grid.Options.Selection.AutoFill := True;
// Visual customisation: make the fill handle more prominent
Grid.AutoFillAppearance.HandleSize := 8;
Grid.AutoFillAppearance.HandleColor := $00003399;
Grid.AutoFillAppearance.PreviewStroke.Color := $00003399;
Grid.AutoFillAppearance.PreviewStroke.Width := 2;
// Custom list lookup — return the registered list when AutoFill asks
Grid.OnAutoFillGetCustomList := GridAutoFillGetCustomList;
end;
procedure TForm1.GridAutoFillGetCustomList(Sender: TObject;
AColumn, ARow: Integer; var AList: TArray<string>);
begin
AList := Grid.AutoFillCustomListGet('Days');
end;
Visual customisation
The fill handle and preview rectangle styling lives in
Grid.AutoFillAppearance — change handle size, fill colour, preview stroke,
and other visual properties.
Related API
Grid.Options.Selection.AutoFillGrid.Options.Selection.Mode— must begsmCellRangeGrid.AutoFill(SourceStart, SourceEnd, TargetStart, TargetEnd)Grid.AutoFillCustomListSet(Name, Values)OnAutoFillCalculateValue— full calculation overrideOnAutoFillGetCustomList— dynamic list lookupTTMSFNCDataGridAutoFillAppearance
See also
- Editing cells — autofill works alongside inplace editing.
- Demo:
Demo/FMX/DataGrid/Basic/AutoFill