Skip to main content
Table of Contents

Items, Appearance, and Editing

TTMSFNCListEditor presents editable values as individual items. Use it for address lists, tags, roles, filters, and other compact collections where users add, select, update, or remove short text values.

List editor

Populate Items

Add values through Items. Each item stores display Text, an optional Value, optional left and right images, and a Tag for application data.

Populate list editor itemsPascalC++
procedure TForm1.ConfigureListEditor;
var
  itm: TTMSFNCCustomListEditorItem;
begin
  TMSFNCListEditor1.Items.Clear;

  itm := TMSFNCListEditor1.Items.Add;
  itm.Text := 'alice@example.com';
  itm.Value := 'alice';

  itm := TMSFNCListEditor1.Items.Add;
  itm.Text := 'bob@example.com';
  itm.Value := 'bob';
end;

void __fastcall TForm1::ConfigureListEditor()
{
  TTMSFNCCustomListEditorItem *itm;

  TMSFNCListEditor1->Items->Clear();

  itm = TMSFNCListEditor1->Items->Add();
  itm->Text = "alice@example.com";
  itm->Value = "alice";

  itm = TMSFNCListEditor1->Items->Add();
  itm->Text = "bob@example.com";
  itm->Value = "bob";
}
List editor populated with eight e-mail address items wrapping over three rows, one item selected List editor populated with eight e-mail address items wrapping over three rows, one item selected

Style Item States

ItemAppearance controls normal and selected fill, stroke, font color, rounding, and spacing. Use the default image properties when most items share the same icon.

Style item appearancePascalC++
procedure TForm1.ConfigureListEditorAppearance;
begin
  TMSFNCListEditor1.ItemAppearance.HorizontalSpacing := 6;
  TMSFNCListEditor1.ItemAppearance.VerticalSpacing := 6;
  TMSFNCListEditor1.ItemAppearance.RoundingNormal := 4;
  TMSFNCListEditor1.ItemAppearance.RoundingSelected := 4;
  TMSFNCListEditor1.ItemAppearance.FillSelected.Color := gcSteelblue;
  TMSFNCListEditor1.ItemAppearance.FontColorSelected := gcWhite;
end;

void __fastcall TForm1::ConfigureListEditorAppearance()
{
  TMSFNCListEditor1->ItemAppearance->HorizontalSpacing = 6;
  TMSFNCListEditor1->ItemAppearance->VerticalSpacing = 6;
  TMSFNCListEditor1->ItemAppearance->RoundingNormal = 4;
  TMSFNCListEditor1->ItemAppearance->RoundingSelected = 4;
  TMSFNCListEditor1->ItemAppearance->FillSelected->Color = gcSteelblue;
  TMSFNCListEditor1->ItemAppearance->FontColorSelected = gcWhite;
}

Item Images

Assign BitmapContainer before setting image names. Use per-item LeftImageName and RightImageName for item-specific visuals, or DefaultLeftImageName and DefaultRightImageName for shared defaults.

Add item imagesPascalC++
procedure TForm1.ConfigureListEditorImages;
begin
  TMSFNCListEditor1.BitmapContainer := TMSFNCBitmapContainer1;
  TMSFNCListEditor1.ItemAppearance.DefaultLeftImageName := 'person';
  TMSFNCListEditor1.ItemAppearance.DefaultRightImageName := 'remove';

  TMSFNCListEditor1.Items[0].RightImageName := 'favorite';
end;

void __fastcall TForm1::ConfigureListEditorImages()
{
  TMSFNCListEditor1->BitmapContainer = TMSFNCBitmapContainer1;
  TMSFNCListEditor1->ItemAppearance->DefaultLeftImageName = "person";
  TMSFNCListEditor1->ItemAppearance->DefaultRightImageName = "remove";

  TMSFNCListEditor1->Items->Items[0]->RightImageName = "favorite";
}

Editing Events

Use item events to validate or react to changes. OnItemCanDelete can prevent deletion, OnItemUpdate can normalize text, and OnItemInsert / OnItemDelete can sync external state.

Validate item editsPascalC++
procedure TForm1.ConfigureListEditorEvents;
begin
  TMSFNCListEditor1.OnItemCanDelete := TMSFNCListEditor1ItemCanDelete;
  TMSFNCListEditor1.OnItemUpdate := TMSFNCListEditor1ItemUpdate;
end;

procedure TForm1.TMSFNCListEditor1ItemCanDelete(Sender: TObject;
  AItemIndex: Integer; var ACanDelete: Boolean);
begin
  ACanDelete := TMSFNCListEditor1.Items[AItemIndex].Value <> 'required';
end;

procedure TForm1.TMSFNCListEditor1ItemUpdate(Sender: TObject;
  AItemIndex: Integer; var AText: string);
begin
  AText := Trim(AText);
end;

void __fastcall TForm1::ConfigureListEditorEvents()
{
  TMSFNCListEditor1->OnItemCanDelete = TMSFNCListEditor1ItemCanDelete;
  TMSFNCListEditor1->OnItemUpdate = TMSFNCListEditor1ItemUpdate;
}

void __fastcall TForm1::TMSFNCListEditor1ItemCanDelete(TObject *Sender,
  int AItemIndex, bool &ACanDelete)
{
  ACanDelete = TMSFNCListEditor1->Items->Items[AItemIndex]->Value != "required";
}

void __fastcall TForm1::TMSFNCListEditor1ItemUpdate(TObject *Sender,
  int AItemIndex, System::UnicodeString &AText)
{
  AText = Trim(AText);
}

Custom Editor Behavior

The editor lifecycle events let you adjust editor size, provide editor text, or replace the editor class. Keep these handlers small and deterministic because they are called while the control recalculates item layout.

Use as a Control Picker Source

TTMSFNCCustomListEditor implements ITMSFNCControlPickerItems, so a TTMSFNCListEditor can act as the embedded drop-down content of a TMS FNC Control Picker. This is useful when you want the compact chip-based editing experience of the list editor to appear inside a drop-down that opens from a text field, rather than staying always visible on the form. Assign the list editor instance to the picker's Control property; the picker then reads the item count, item size, and selection through the interface to size and drive its drop-down.

Use a ListEditor as a ControlPicker's drop-down contentPascalC++
procedure TForm1.ConfigureListEditorAsControlPickerSource;
var
  itm: TTMSFNCCustomListEditorItem;
begin
  TMSFNCListEditor1.Items.Clear;

  itm := TMSFNCListEditor1.Items.Add;
  itm.Text := 'Admin';

  itm := TMSFNCListEditor1.Items.Add;
  itm.Text := 'Editor';

  itm := TMSFNCListEditor1.Items.Add;
  itm.Text := 'Viewer';

  TMSFNCControlPicker1.Control := TMSFNCListEditor1;
end;

void __fastcall TForm1::ConfigureListEditorAsControlPickerSource()
{
  TTMSFNCCustomListEditorItem *itm;

  TMSFNCListEditor1->Items->Clear();

  itm = TMSFNCListEditor1->Items->Add();
  itm->Text = "Admin";

  itm = TMSFNCListEditor1->Items->Add();
  itm->Text = "Editor";

  itm = TMSFNCListEditor1->Items->Add();
  itm->Text = "Viewer";

  TMSFNCControlPicker1->Control = TMSFNCListEditor1;
}

Combining items, images, appearance, and editing events

The following example builds a tag-editor for user roles, applies a green appearance for confirmed roles, and prevents deletion of the last remaining item:

Combining items, images, appearance, and editing eventsPascalC++
procedure TForm1.FormCreate(Sender: TObject);
var
  Item: TTMSFNCCustomListEditorItem;
  Role: string;
begin
  TMSFNCListEditor1.BitmapContainer := BitmapContainer1;

  { Seed with existing roles. Items.Add returns the new item, so its text and
    image can be set straight away. }
  for Role in ['Admin', 'Editor', 'Viewer'] do
  begin
    Item := TMSFNCListEditor1.Items.Add;
    Item.Text := Role;
    Item.LeftImageName := 'role-' + LowerCase(Role);
  end;

  TMSFNCListEditor1.ItemAppearance.FillNormal.Color := gcHoneydew;
  TMSFNCListEditor1.ItemAppearance.StrokeNormal.Color := gcSeagreen;
end;

{ The editing events pass an item INDEX, not the item itself - reach the item
  through Items[AItemIndex] when you need it. }
procedure TForm1.TMSFNCListEditor1ItemCanDelete(Sender: TObject;
  AItemIndex: Integer; var ACanDelete: Boolean);
begin
  ACanDelete := TMSFNCListEditor1.Items.Count > 1; // keep at least one role
end;

procedure TForm1.TMSFNCListEditor1ItemInsert(Sender: TObject;
  AItemIndex: Integer);
var
  Item: TTMSFNCCustomListEditorItem;
begin
  Item := TMSFNCListEditor1.Items[AItemIndex];
  Item.LeftImageName := 'role-custom';
  LogChange('Role added: ' + Item.Text);
end;
void __fastcall TForm1::FormCreate(TObject *Sender)
{
  TTMSFNCCustomListEditorItem *Item;
  const System::UnicodeString Roles[3] = {"Admin", "Editor", "Viewer"};

  TMSFNCListEditor1->BitmapContainer = BitmapContainer1;

  // Seed with existing roles. Items.Add returns the new item, so its text and
  // image can be set straight away.
  for (int i = 0; i < 3; i++)
  {
    Item = TMSFNCListEditor1->Items->Add();
    Item->Text = Roles[i];
    Item->LeftImageName = "role-" + LowerCase(Roles[i]);
  }

  TMSFNCListEditor1->ItemAppearance->FillNormal->Color = gcHoneydew;
  TMSFNCListEditor1->ItemAppearance->StrokeNormal->Color = gcSeagreen;
}

// The editing events pass an item INDEX, not the item itself - reach the item
// through Items[AItemIndex] when you need it.
void __fastcall TForm1::TMSFNCListEditor1ItemCanDelete(TObject *Sender,
  int AItemIndex, bool &ACanDelete)
{
  ACanDelete = TMSFNCListEditor1->Items->Count > 1; // keep at least one role
}

void __fastcall TForm1::TMSFNCListEditor1ItemInsert(TObject *Sender,
  int AItemIndex)
{
  TTMSFNCCustomListEditorItem *Item;

  Item = TMSFNCListEditor1->Items->Items[AItemIndex];
  Item->LeftImageName = "role-custom";
  LogChange("Role added: " + Item->Text);
}
Role tag editor with a per-role left image, a shared remove image on the right, and the green honeydew and sea-green item appearance, with the Editor role selected Role tag editor with a per-role left image, a shared remove image on the right, and the green honeydew and sea-green item appearance, with the Editor role selected

See also