Table of Contents

Rules and Actions

A rule pairs a filter expression with one or more actions. When you call Apply, the manager resolves the items named by the rule's ItemsPath, evaluates the expression against each one, and runs every action — writing one set of property values on a match and (optionally) a different set on a no-match. Reach for an explicit rule plus actions when a single helper such as ShowWhere is not enough: when you need to write more than one property, target a custom property path, or supply distinct match, no-match, and inactive values. This guide covers building a rule, adding the different action kinds, and the three value states every action understands.

Anatomy of a rule

A TTMSFNCFilterRule exposes the parts you configure:

Member Role
Source Root component the RTTI path resolver navigates from.
ItemsPath RTTI path to the items to evaluate (e.g. Items[*]); empty targets Source itself.
FilterText The expression — see Filter expressions. Empty matches all items.
Actions The property assignments applied per item.
Active When False, each action's inactive value is applied instead of evaluating the filter.

Add a rule with AddRule, then attach actions. AddRule does not apply by itself — call Apply on the manager once the rules are configured.

Adding actions

Each action writes one target property. AddAction takes an RTTI target path and up to three values — match, no-match, and inactive — so you control exactly what happens in every state. AddVisibilityAction and AddEnableAction are shorthands for the two most common cases (Visible and Enabled), and AddDisableAction inverts the enable logic. Every fluent helper returns the rule, so calls chain.

uses
  TMS.TMSFNCFilterRulesManager, System.Rtti;

{ Inside a method of your form, with FilterRulesManager1 and Planner1 on it: }
var
  Rule: TTMSFNCFilterRule;
begin
  // Create a rule whose expression selects the "Open" items. Field references
  // use [brackets]; string literals use single quotes.
  Rule := FilterRulesManager1.AddRule('HighlightOpen', Planner1, 'Items[*]',
    '[Status] = ''Open''');

  // One explicit action covering all three states: written on match,
  // on no-match, and when the rule is later set inactive.
  Rule.AddAction('Visible',
    TValue.From<Boolean>(True),    // match
    TValue.From<Boolean>(False),   // no-match
    TValue.From<Boolean>(True));   // inactive -> everything visible again

  // Fluent helpers add the two most common actions; each returns the rule.
  Rule.AddEnableAction(True);

  FilterRulesManager1.Apply;
end;

Match, no-match, and inactive values

The three-argument form of AddAction maps directly to the rule lifecycle:

  • Match value — written to the target when the expression matches the item.
  • No-match value — written when it does not. Omit it to leave non-matching items untouched.
  • Inactive value — written to every item when the rule's Active is False (or when you call ApplyInactive). Use it to define a clean "filter off" state, such as making all items visible again.

Values are TTMSFNCValue (an alias for TValue), so any type the target property accepts is valid — TValue.From<Boolean>(True), TValue.From<Integer>(0), a string, or a color.

Combining several actions on one rule

A single rule can drive visibility, enabled state, and a custom property at once. Because each fluent call returns the rule, the whole configuration reads as one chain, and toggling Active flips all of them together:

uses
  TMS.TMSFNCFilterRulesManager, System.Rtti;

{ Inside a method of your form: }
var
  Rule: TTMSFNCFilterRule;
begin
  Rule := FilterRulesManager1.AddRule('Overdue', Planner1, 'Items[*]',
    '[DaysLate] > 0');

  // Three different actions fire from the same match result. Each fluent
  // call returns the rule, so they chain.
  Rule
    .AddVisibilityAction(True)                          // Visible := matches
    .AddEnableAction(True)                              // Enabled := matches
    .AddAction('Tag',
       TValue.From<Integer>(1),                         // match -> Tag 1
       TValue.From<Integer>(0));                         // no-match -> Tag 0

  FilterRulesManager1.Apply;

  // Deactivating pushes each action's inactive value (or restores defaults)
  // without removing the rule, so the filter can be toggled at runtime.
  Rule.Active := False;
  FilterRulesManager1.Apply;
end;

Common pitfalls

  • Nothing changes until Apply. AddRule and the AddAction family only configure the rule; the manager writes values when you call Apply.
  • A rule with no action is a no-op. The expression is evaluated but there is nothing to write — always add at least one action.
  • Set an inactive value if you toggle rules. Without one, deactivating a rule leaves the last match/no-match values in place rather than restoring a neutral state.
  • ItemsPath resolves on Source. A path such as Items[*] must exist on the source component; an empty path applies the actions to Source directly.

See also