Table of Contents

Selection

The Interaction guide covers the user-facing selection switches — MultiSelect, ShowSelection, KeepSelection. This guide covers the programmatic side: how to read what is selected, select items from code, select a whole batch by criteria, and veto or react to selection changes. Reach for this when the app drives the selection itself — a "select all overdue", a master/detail panel that follows the selection, or a bulk recolor/delete over the chosen items. The current selection is exposed as a live TTMSFNCPlannerSelectedItems list (TList<TTMSFNCPlannerItem>), so reading and iterating it is just list code.

A week planner with the three morning meetings selected (shown in orange) and two afternoon items unselected (blue) The same planner with the morning meetings selected, in a dark theme

Enabling multi-select

A single click always selects one item. To hold more than one in the selection, turn on Interaction.MultiSelect first — every example below assumes it is on:

{ Inside your form's OnCreate event: }
Planner1.Interaction.MultiSelect := True;

With MultiSelect off, SelectItem still works but each call replaces the previous selection rather than extending it.

Selecting items in code

The planner exposes two ways to select:

  • SelectItem(AItem) / SelectItem(AItemIndex) — add one item, by instance or by index.
  • SelectItems(AItems) — add several at once. AItems is a TTMSFNCPlannerItemArray, which is an array of item indexes (array of Integer), not an array of item objects.
  • UnselectAllItems clears the selection.

This example clears the selection, then walks the Items collection and selects every appointment that starts before noon, and shows the index-based overload:

procedure TForm1.SelectMorningMeetings;
var
  i: Integer;
  it: TTMSFNCPlannerItem;
begin
  // Multi-select must be on before more than one item can be selected.
  Planner1.Interaction.MultiSelect := True;

  Planner1.BeginUpdate;
  try
    // Start from a clean selection.
    Planner1.UnselectAllItems;

    // Select every item that starts before noon by walking the Items collection.
    for i := 0 to Planner1.Items.Count - 1 do
    begin
      it := Planner1.Items[i];
      if Frac(it.StartTime) < 0.5 then   // 0.5 = 12:00
        Planner1.SelectItem(it);          // overload taking the item instance
    end;
  finally
    Planner1.EndUpdate;
  end;

  // SelectedItems is a live TList<TTMSFNCPlannerItem> — read it back.
  Caption := Format('%d morning item(s) selected', [Planner1.SelectedItems.Count]);
end;

procedure TForm1.SelectFirstThreeByIndex;
var
  indexes: TTMSFNCPlannerItemArray;   // = array of Integer (item indexes)
begin
  // SelectItems takes item indexes, not item objects.
  indexes := [0, 1, 2];
  Planner1.SelectItems(indexes);
end;

Read the result back through SelectedItems — it always reflects the current state, whether the user or your code made the selection.

Vetoing and reacting to changes

Two events bracket every selection change:

  • OnBeforeSelectItem fires first with a var ACanSelect — set it to False to block the item from being selected at all.
  • OnAfterSelectItem fires once the item is selected, with the item as its parameter — the place to update a details panel.
procedure TForm1.WireSelectionEvents;
begin
  Planner1.OnBeforeSelectItem := PlannerBeforeSelectItem;
  Planner1.OnAfterSelectItem := PlannerAfterSelectItem;
end;

procedure TForm1.PlannerBeforeSelectItem(Sender: TObject;
  AItem: TTMSFNCPlannerItem; var ACanSelect: Boolean);
begin
  // Refuse selection of read-only items. Setting ACanSelect to False
  // cancels the selection before it happens.
  if not AItem.Editable then
    ACanSelect := False;
end;

procedure TForm1.PlannerAfterSelectItem(Sender: TObject;
  AItem: TTMSFNCPlannerItem);
begin
  // Fires once the selection has been applied. AItem is the item just selected.
  if Assigned(AItem) then
  begin
    LabelTitle.Text := AItem.Title;
    LabelWhen.Text := Format('%s - %s',
      [TimeToStr(AItem.StartTime), TimeToStr(AItem.EndTime)]);
  end;
end;

Putting it together

This combines the pieces into one workflow: enable multi-select, install a veto so locked items can never be selected, select a batch by criteria, then run a bulk operation that reads SelectedItems and recolors every chosen item:

procedure TForm1.ColorSelectedItems;
var
  i: Integer;
begin
  // Recolor every currently selected item. SelectedItems is read live, so this
  // works whether the user selected with the mouse or the code selected by
  // criteria (see SelectMorningMeetings).
  Planner1.BeginUpdate;
  try
    for i := 0 to Planner1.SelectedItems.Count - 1 do
      Planner1.SelectedItems[i].Color := gcTomato;
  finally
    Planner1.EndUpdate;
  end;
end;

procedure TForm1.SetUpSelectionWorkflow;
begin
  // 1. Allow multiple items to be selected at once.
  Planner1.Interaction.MultiSelect := True;

  // 2. Block locked items from ever entering the selection.
  Planner1.OnBeforeSelectItem := PlannerBeforeSelectItem;

  // 3. Select a batch by criteria, then act on the whole selection at once.
  SelectMorningMeetings;
  ColorSelectedItems;
end;

Pitfalls

  • SelectItems takes indexes, not items. TTMSFNCPlannerItemArray is array of Integer. Pass [0, 1, 2] (item indexes); passing item objects will not compile. Use SelectItem(AItem) when you have the instance.
  • Multi-select must be on to accumulate. With Interaction.MultiSelect = False, each SelectItem replaces the selection — a loop ends with only the last item selected.
  • SelectedItems is non-owning. It tracks the selection; never free items through it. Add and remove items through the Items collection.
  • Batch programmatic selection. Wrap a selection loop in BeginUpdate / EndUpdate so the planner repaints once, not after every SelectItem.
  • A vetoed item never reaches OnAfterSelectItem. If OnBeforeSelectItem sets ACanSelect := False, the after event does not fire for that item.

See also

  • Interaction — the user-facing selection switches
  • Items — the Items collection and per-item properties
  • Appearance — styling the selection overlay and selected items