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:
FilterExpressions— explicit per-value overrides.DefaultFilterProperties— field name, type, and operator applied when no expression matches.- Raw value — for numeric controls (TrackBar, RangeSlider), the numeric value is used directly if
FilterExpressionsis 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;