Table of Contents

Expressions and Custom Controls

Every filter control in TTMSFNCFilterView is backed by the expression system — a layer that maps UI values to typed filter expressions and writes the result to a TTMSFNCFilterStructure. Understanding expressions lets you customise the generated filter text, handle unknown values, and integrate controls that are not part of the FilterView family.


How expressions work

Each filter control manages a FilterExpressions collection (TTMSFNCFilterViewExpressions). When the control's value changes, FilterView looks up the new value in the collection and applies the matching expression to the filter structure. If no match is found, DefaultFilterProperties are used as a fallback.

The three layers in priority order:

  1. FilterExpressions — explicit per-value overrides.
  2. DefaultFilterProperties — field name, type, and operator applied when no expression matches.
  3. Raw value — for numeric controls (TrackBar, RangeSlider), the numeric value is used directly if FilterExpressions is empty and no default is set.

TTMSFNCFilterViewExpression

A single TTMSFNCFilterViewExpression links one UI value to one filter condition.

Property Description
PropertyValue The UI identifier — typically the item text or index string.
FilterFieldName The field or property name in the filter output.
FilterFieldType Data type: fdtAutomatic, fdtText, fdtBoolean, fdtDateTime, fdtDate, fdtTime, fdtFloat, fdtNumber.
ExpressionOperator Comparison: feoEqual, feoNotEqual, feoLargerThan, feoSmallerThan, feoLargerThanOrEqual, feoSmallerThanOrEqual, etc.
FilterValueText The value written to the filter, parsed according to FilterFieldType.
AddToFilter When False the expression exists in the collection but is excluded from the filter output — useful for "no filter" / "all" options.

Add an expression to a combo box filter control in code:

var
  expr: TTMSFNCFilterViewExpression;
begin
  expr := FilterViewComboBox1.FilterExpressions.Add;
  expr.PropertyValue   := 'Active';          // must match the item text exactly
  expr.FilterFieldName := 'Status';
  expr.FilterFieldType := fdtText;
  expr.ExpressionOperator := feoEqual;
  expr.FilterValueText := 'Active';
  expr.AddToFilter := True;

  // "All" option — item is shown but generates no filter clause
  expr := FilterViewComboBox1.FilterExpressions.Add;
  expr.PropertyValue := 'All';
  expr.AddToFilter   := False;
end;

TTMSFNCFilterViewExpressions

TTMSFNCFilterViewExpressions is the collection exposed on each filter control.

Key methods:

Method Description
AddOrUpdateExpression(propertyValue, filterValueText) Adds or updates the expression for propertyValue.
AddOrUpdateExpression(propertyValue, filterValueText, addToFilter) Same with explicit AddToFilter flag.
AddOrUpdateExpression(propertyValue, operator, filterValueText, addToFilter) Full override — sets all expression properties.
Add Adds an empty expression; configure it in the returned object.
AddFilterItem Writes the current expression state to the filter structure.
RemoveFilterItem Removes the associated filter structure item.
UpdateFilterItem Syncs a changed value back to the filter structure.

Key events:

Event Description
OnChanged Raised when any expression in the collection changes.
OnExpressionNotFound Raised when the control's current value does not match any expression. Use this to handle dynamic or user-typed values.
OnSetFilterItem Raised just before writing to the filter structure; lets you change field name, type, or operator at runtime.

Use AddOrUpdateExpression to keep a filter expression in sync without reconstructing the entire collection:

// After the user changes a spinner or typed value:
FilterViewComboBox1.FilterExpressions.AddOrUpdateExpression(
  'High',       // PropertyValue
  feoEqual,     // ExpressionOperator
  'High',       // FilterValueText
  True          // AddToFilter
);

DefaultFilterProperties

TTMSFNCFilterViewDefaultExpression is exposed as DefaultFilterProperties on each control. It acts as the catch-all when FilterExpressions has no match for the current value.

Property Description
FilterFieldName Default field name.
FilterFieldType Default data type. Use fdtAutomatic to let FilterView infer the type.
ExpressionOperator Default operator.

Configure DefaultFilterProperties on a track bar to filter a numeric field by the current slider position:

FilterViewTrackBar1.DefaultFilterProperties.FilterFieldName := 'Price';
FilterViewTrackBar1.DefaultFilterProperties.FilterFieldType := fdtNumber;
FilterViewTrackBar1.DefaultFilterProperties.ExpressionOperator := feoSmallerThanOrEqual;

Handling unknown values with OnExpressionNotFound

When a user types a value that does not exist in FilterExpressions, OnExpressionNotFound fires. Use it to create or synthesise an expression on the fly:

procedure TFormFilterView.FilterExpressionsExpressionNotFound(
  Sender: TTMSFNCFilterViewExpressions;
  APropertyValue: string;
  var AExpression: TTMSFNCFilterViewExpression);
begin
  // Dynamically create an expression for any typed value
  AExpression := Sender.Add;
  AExpression.PropertyValue := APropertyValue;
  AExpression.FilterFieldName := 'Tag';
  AExpression.FilterFieldType := fdtText;
  AExpression.ExpressionOperator := feoContains;
  AExpression.FilterValueText := APropertyValue;
end;

Custom controls

AddCustomItemControl

Use AddCustomItemControl to register any existing control — one not derived from the FilterView family — as a filter source. You then call UpdateCustomItemControlValue from the control's change event to keep the filter in sync:

uses
  FMX.TMSFNCFilterView, TMS.TMSFNCFilterBuilder;

// Register any existing control as a filter item
procedure TFormFilterView.AddCustomCalendarFilter;
begin
  // Adds the calendar's current date as a filter on the 'Date' field
  FilterView.AddCustomItemControl(
    TMSFNCCalendar, TMSFNCCalendar.SelectedDate, 'Date', fdtDate);
end;

// Update the filter whenever the calendar selection changes
procedure TFormFilterView.TMSFNCCalendarDateSelected(Sender: TObject; ADate: TDate);
begin
  FilterView.UpdateCustomItemControlValue(TMSFNCCalendar, ADate);
end;

// ControlContainer: embed any control; update filter from its event
procedure TFormFilterView.CalendarDateSelected(Sender: TObject; ADate: TDate);
begin
  TMSFNCFilterViewControlContainer1.FilterExpression.FilterValue := ADate;
  TMSFNCFilterViewControlContainer1.FilterExpression.AddToFilter := ADate <> 0;
end;

Related methods:

Method Description
AddCustomItemControl(control, value, fieldName, fieldType) Registers the control and creates its filter structure item.
UpdateCustomItemControlValue(control, value) Updates the filter value when the control changes. Returns True on success.
GetCustomItemControlFilterItem(control) Returns the filter structure item for the control; useful for advanced customisation.
RemoveCustomItemControl(control) Unregisters the control and removes its filter item.
AddCustomGroupControl(control, collection) Creates a filter group (AND/OR) associated with the control.
UpdateCustomGroupControlOperator(control, operator) Changes the group's logical operator at runtime.

ControlContainer

TTMSFNCFilterViewControlContainer is a panel that holds any child control. Unlike AddCustomItemControl, the container is designed to wrap one control inside the FilterView's layout:

// Drop any control inside the container at design time, then
// update FilterExpression from its event handler at runtime.
procedure TFormFilterView.CalendarDateSelected(Sender: TObject; ADate: TDate);
begin
  TMSFNCFilterViewControlContainer1.FilterExpression.FilterValue := ADate;
  TMSFNCFilterViewControlContainer1.FilterExpression.AddToFilter := ADate <> 0;
end;

Key property:

Property Description
FilterExpression The single expression updated directly from the host control's event.

Filter format types

The FilterFormatType property on TTMSFNCFilterView controls the shape of the generated FilterText:

Value Output format
fftDelphiDataSet Delphi TDataSet.Filter expression syntax
fftUniversalFilterExpressions Generic key=value expression syntax

Change FilterFormatType at design time or before the first filter is generated; FilterParseFormat is updated automatically.

// For a TDataSet-backed grid
FilterView1.FilterFormatType := fftDelphiDataSet;

// For a custom list that parses its own filter text
FilterView1.FilterFormatType := fftUniversalFilterExpressions;

Reacting to filter changes

fv.OnFilterTextChanged := DoFilterTextChanged;

procedure TFormFilterView.DoFilterTextChanged(Sender: TObject; AFilterText: string);
begin
  // Apply filter text to a dataset, list, or custom data source
  DataSource.DataSet.Filter := AFilterText;
  DataSource.DataSet.Filtered := AFilterText <> '';
end;

Additional parse events let you suppress or rewrite individual items before they reach the final output:

Event Description
OnFilterTextParse Raised before the full parse begins; set ACancel := True to abort.
OnFilterTextParsed Raised after parsing; modify AFilterText for post-processing.
OnFilterViewGroupParse Raised per group; set AExclude := True to omit the group.
OnFilterViewGroupParsed Raised after a group is built; modify AGroupText.
OnFilterViewItemParse Raised per item; set ASkip := True to exclude one item from the output.

Tips and troubleshooting

Filter not updating after control change : Verify that the expression has AddToFilter = True. A common cause is clearing FilterExpressions and not re-adding the required entries.

Radio buttons not mutually exclusive : Set the same GroupName on all related TTMSFNCFilterViewRadioButton controls.

Dataset filter rejects the text : TDataSet.Filter is strict — field names must match exactly and values must be correctly quoted. Use OnFilterTextParsed or OnSetFilterItem to normalise the output before it reaches the dataset. Also ensure expressions are fully configured before setting Parent (which triggers the first filter structure sync).

Performance with many controls : Wrap the initial control creation in BeginUpdate / EndUpdate on the FilterView to batch structure rebuilds and prevent flickering.


Combining DefaultFilterProperties, OnExpressionNotFound, and filter format types

Use a dataset-compatible format, configure a default fallback, and handle unknown typed values together so the filter works for both list and free-text inputs:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FilterView1.FilterFormatType := fftDelphiDataSet;

  FilterViewComboBox1.DefaultFilterProperties.FilterFieldName     := 'Status';
  FilterViewComboBox1.DefaultFilterProperties.FilterFieldType     := fdtText;
  FilterViewComboBox1.DefaultFilterProperties.ExpressionOperator  := feoEqual;
  FilterViewComboBox1.FilterExpressions.OnExpressionNotFound :=
    FilterExpressionsExpressionNotFound;
  FilterViewComboBox1.Parent := FilterView1;

  FilterView1.OnFilterTextChanged := DoFilterTextChanged;
end;

procedure TForm1.DoFilterTextChanged(Sender: TObject; AFilterText: string);
begin
  DataSource.DataSet.Filter   := AFilterText;
  DataSource.DataSet.Filtered := AFilterText <> '';
end;

procedure TForm1.FilterExpressionsExpressionNotFound(
  Sender: TTMSFNCFilterViewExpressions;
  APropertyValue: string;
  var AExpression: TTMSFNCFilterViewExpression);
begin
  AExpression := Sender.Add;
  AExpression.PropertyValue      := APropertyValue;
  AExpression.FilterFieldName    := 'Status';
  AExpression.FilterFieldType    := fdtText;
  AExpression.ExpressionOperator := feoContains;
  AExpression.FilterValueText    := APropertyValue;
end;

See also