Table of Contents

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: OnCellEditGetData and OnCellEditSetData are the right place for unit conversions, lookup formatting, or any round-trip transform. For simple validation (range checks, required fields), OnCellEditValidateData is cleaner than OnBeforeCloseInplaceEditor because it receives the parsed TValue rather 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;
  • TTMSFNCDataGrid.Options.Editing
  • TTMSFNCDataGrid.Options.Lookup
  • TTMSFNCDataGrid.Lookup
  • TTMSFNCDataGrid.LookupInColumn
  • TTMSFNCDataGrid.LookupInColumnFromRow
  • OnBeforeOpenInplaceEditor / OnAfterOpenInplaceEditor
  • OnBeforeInplaceEditorGetValue / OnAfterInplaceEditorGetValue
  • OnBeforeInplaceEditorSetValue / OnAfterInplaceEditorSetValue
  • OnBeforeCloseInplaceEditor / OnAfterCloseInplaceEditor
  • OnBeforeExitInplaceEditor / OnAfterExitInplaceEditor
  • OnCellEditGetData — 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 with AValid := False.
  • OnBeforeLookup / OnAfterLookup

See also