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. |
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.
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.