Inplace editor events
Intercept value transfer, customize editor creation, validate close/exit, and use keyboard lookup when editing is disabled.
Overview
The basic Editing cells guide covers enabling editors and choosing editor types. This chapter focuses on the event points around the editor lifecycle.
| Stage | Events |
|---|---|
| Open editor | OnBeforeOpenInplaceEditor, OnAfterOpenInplaceEditor |
| Load value into editor | OnBeforeInplaceEditorGetValue, OnAfterInplaceEditorGetValue |
| Write value back | OnBeforeInplaceEditorSetValue, OnAfterInplaceEditorSetValue |
| Close editor | OnBeforeCloseInplaceEditor, OnAfterCloseInplaceEditor |
| Grid focus leaves | OnBeforeExitInplaceEditor, OnAfterExitInplaceEditor |
| Keyboard lookup | Options.Lookup, OnBeforeLookup, OnAfterLookup |
Open and close
Prevent editing for specific cells in OnBeforeOpenInplaceEditor:
procedure TForm1.GridBeforeOpenInplaceEditor(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
var AValue: TTMSFNCDataGridCellValue; var ACanOpen: Boolean);
begin
if ACell.Column = ReadOnlyColumn then
ACanOpen := False;
end;
Validate before the editor closes:
procedure TForm1.GridBeforeCloseInplaceEditor(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
AInplaceEditor: TTMSFNCDataGridInplaceEditor;
ACancelled: Boolean;
var AValue: TTMSFNCDataGridCellValue;
var ACanClose: Boolean);
begin
if not ACancelled and AValue.IsEmpty then
begin
ShowMessage('Value is required.');
ACanClose := False;
end;
end;
Use exit events when focus leaves the grid entirely. Use close events when an edit session ends while the grid remains active.
Value transfer
Use the "before" value events to override the default transfer.
procedure TForm1.GridBeforeInplaceEditorGetValue(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
AInplaceEditor: TTMSFNCDataGridInplaceEditor;
var AValue: TTMSFNCDataGridCellValue; var AHandled: Boolean);
begin
if ACell.Column = AmountColumn then
begin
AValue.AsString := FormatFloat('0.00', AValue.AsFloat);
AHandled := True;
end;
end;
Validate before writing back:
procedure TForm1.GridBeforeInplaceEditorSetValue(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
AInplaceEditor: TTMSFNCDataGridInplaceEditor;
var AValue: TTMSFNCDataGridCellValue; var AHandled: Boolean);
begin
if (ACell.Column = QuantityColumn) and (AValue.AsInteger < 0) then
begin
ShowMessage('Quantity cannot be negative.');
AHandled := True;
end;
end;
Data-level cell edit events
Three events operate at the data layer rather than the renderer layer. They receive TTMSFNCDataGridCellValue directly and fire independently of which editor type is active — including custom editors.
| Event | When it fires | What you can do |
|---|---|---|
OnCellEditGetData |
Just before the editor is loaded with the cell's current value. | Replace the value the editor sees (e.g. reformat it). |
OnCellEditSetData |
Just before the edited value is written back to the cell. | Transform the value before it is stored (e.g. strip whitespace, apply units). |
OnCellEditValidateData |
Before the edit is accepted; AValid defaults to True. |
Reject invalid input by setting AValid := False. The editor stays open with the rejected text still in it, so the user corrects what they typed instead of retyping it from scratch; the grid does not move to the next cell. |
procedure TForm1.GridCellEditGetData(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
AInplaceEditor: TTMSFNCDataGridInplaceEditor;
var AValue: TTMSFNCDataGridCellValue);
begin
// Show stored temperature in °F; it is stored in °C
if ACell.Column = TempColumn then
AValue := TValue.From<Double>(AValue.AsExtended * 9 / 5 + 32);
end;
procedure TForm1.GridCellEditSetData(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
AInplaceEditor: TTMSFNCDataGridInplaceEditor;
var AValue: TTMSFNCDataGridCellValue);
begin
// Convert °F back to °C before storing
if ACell.Column = TempColumn then
AValue := TValue.From<Double>((AValue.AsExtended - 32) * 5 / 9);
end;
procedure TForm1.GridCellEditValidateData(Sender: TObject;
ACell: TTMSFNCDataGridCellCoord;
AInplaceEditor: TTMSFNCDataGridInplaceEditor;
var AValue: TTMSFNCDataGridCellValue;
var AValid: Boolean);
begin
// Reject negative temperatures in Kelvin column
if ACell.Column = KelvinColumn then
AValid := AValue.AsFloat >= 0;
end;
Tip:
OnCellEditGetDataandOnCellEditSetDataare the right place for unit conversions, lookup formatting, or any round-trip transform. For simple validation (range checks, required fields),OnCellEditValidateDatais cleaner thanOnBeforeCloseInplaceEditorbecause it receives the parsedTValuerather than a raw string.
Custom editors and the first keystroke
When the user starts editing by typing rather than by pressing F2 (see the
direct-edit shortcuts in Editing), the character that triggered
the edit is not lost: it is handed to the editor as its initial value, so
"type 4 to start editing" leaves a 4 in the editor rather than an empty box.
This holds for custom editors too. A getCustom editor built on an edit or memo
control receives that first character the same way the built-in editors do, so a
column with a custom editor behaves like every other column when the user just
starts typing. An editor that is not text-based — a picker, a checkbox, a button
— simply ignores it.
Keyboard lookup
Keyboard lookup moves the focused cell to the first matching value while editing is disabled.
Grid.Options.Editing.Enabled := False;
Grid.Options.Lookup.Enabled := True;
Grid.Options.Lookup.Incremental := True;
Grid.Options.Lookup.CaseSensitive := False;
Grid.Options.Lookup.ResetInterval := 4000;
Programmatic lookup is available too:
Grid.Lookup('Smith', True, True);
Grid.LookupInColumn(1, 'Smith');
Grid.LookupInColumnFromRow(1, 5, 'Smith');
Use OnBeforeLookup to modify or cancel the search string:
procedure TForm1.GridBeforeLookup(Sender: TObject;
var ALookupString: string; var ACanLookup: Boolean);
begin
if Length(ALookupString) < 2 then
ACanLookup := False;
end;
Related API
TTMSFNCDataGrid.Options.EditingTTMSFNCDataGrid.Options.LookupTTMSFNCDataGrid.LookupTTMSFNCDataGrid.LookupInColumnTTMSFNCDataGrid.LookupInColumnFromRowOnBeforeOpenInplaceEditor/OnAfterOpenInplaceEditorOnBeforeInplaceEditorGetValue/OnAfterInplaceEditorGetValueOnBeforeInplaceEditorSetValue/OnAfterInplaceEditorSetValueOnBeforeCloseInplaceEditor/OnAfterCloseInplaceEditorOnBeforeExitInplaceEditor/OnAfterExitInplaceEditorOnCellEditGetData— data-level: override the value loaded into the editor.OnCellEditSetData— data-level: transform the value before it is written back.OnCellEditValidateData— data-level: reject invalid values withAValid := False.OnBeforeLookup/OnAfterLookup
See also
- Editing cells - editor types and validation.
- Keyboard and mouse - navigation and keyboard behavior.