Skip to main content
Table of Contents

Nodes

Node configuration

The NodesAppearance property on TTMSFNCTreeView controls the visual style of all nodes. Individual columns can override these defaults by setting UseDefaultAppearance = False on a TTMSFNCTreeViewColumn.

Adding, inserting, and removing nodes

Both collection-based and virtual modes are covered in Modes. The snippets here use collection-based mode.

Reset the tree to a clean statePascalC++
uses
  FMX.TMSFNCTreeView;

procedure TForm1.ResetTree;
begin
  TreeView1.BeginUpdate;
  TreeView1.ClearNodeList;
  TreeView1.ClearNodes;
  TreeView1.ClearColumns;
  TreeView1.Columns.Add.Text := 'Column 1';
  TreeView1.EndUpdate;
end;
void __fastcall TForm1::ResetTree()
{
  TreeView1->BeginUpdate();
  TreeView1->ClearNodeList();
  TreeView1->ClearNodes();
  TreeView1->ClearColumns();
  TreeView1->Columns->Add()->Text = "Column 1";
  TreeView1->EndUpdate();
}

Add a root node and a child under it:

Add root and child nodesPascalC++
uses
  FMX.TMSFNCTreeView;

procedure TForm1.AddNodes;
var
  root, child: TTMSFNCTreeViewNode;
begin
  // Root node
  root := TreeView1.AddNode;
  root.Text[0] := 'Root Node';

  // Child node — pass the parent to AddNode
  child := TreeView1.AddNode(root);
  child.Text[0] := 'Child Node';

  TreeView1.ExpandNode(root);
end;
void __fastcall TForm1::AddNodes()
{
  // Root node
  TTMSFNCTreeViewNode *root = TreeView1->AddNode();
  root->Text[0] = "Root Node";

  // Child node - pass the parent to AddNode
  TTMSFNCTreeViewNode *child = TreeView1->AddNode(root);
  child->Text[0] = "Child Node";

  TreeView1->ExpandNode(root);
}
Node with child nodes expanded

Insert a node at a specific position, or remove nodes in several ways:

Insert and remove nodesPascalC++
uses
  FMX.TMSFNCTreeView;

procedure TForm1.InsertNodeExample;
begin
  TreeView1.InsertNode(1, nil); // insert at index 1 at root level
end;

procedure TForm1.RemoveNodeExamples(AParent: TTMSFNCTreeViewNode);
begin
  // By method
  TreeView1.RemoveNode(TreeView1.FocusedNode);

  // By freeing the collection item — same result
  TreeView1.FocusedNode.Free;

  // Remove all children of a node
  TreeView1.RemoveNodeChildren(AParent);

  // Remove all selected nodes
  TreeView1.RemoveSelectedNodes;
end;
void __fastcall TForm1::InsertNodeExample()
{
  TreeView1->InsertNode(1, nullptr); // insert at index 1 at root level
}

void __fastcall TForm1::RemoveNodeExamples(TTMSFNCTreeViewNode *AParent)
{
  // By method
  TreeView1->RemoveNode(TreeView1->FocusedNode);

  // By freeing the collection item - same result
  delete TreeView1->FocusedNode;

  // Remove all children of a node
  TreeView1->RemoveNodeChildren(AParent);

  // Remove all selected nodes
  TreeView1->RemoveSelectedNodes();
}

Fixed vs variable node height

Fixed height (default)

All nodes share the same height, set by NodesAppearance.FixedHeight. Icons and text that exceed this height are clipped.

Fixed node heightPascalC++
uses
  FMX.TMSFNCTreeView;

procedure TForm1.SetFixedNodeHeight;
begin
  TreeView1.NodesAppearance.FixedHeight := 40;
end;
void __fastcall TForm1::SetFixedNodeHeight()
{
  TreeView1->NodesAppearance->FixedHeight = 40;
}
Fixed height nodes with oversized icons

Variable height

Set NodesAppearance.HeightMode to tnhmVariable to let each node height expand to fit its content (icon size or wrapped text). The NodesAppearance.VariableMinimumHeight sets the minimum height for scroll calculations.

Treeview nodes advancedPascal
procedure TForm1.SetupVariableHeight;
begin
  TreeView1.BeginUpdate;
  TreeView1.ClearNodeList;
  TreeView1.ClearNodes;
  TreeView1.ClearColumns;
  TreeView1.Columns.Add.Text := 'Variable TreeView';
  TreeView1.Columns[0].WordWrapping := True;
  TreeView1.NodesAppearance.HeightMode := tnhmVariable;
  TreeView1.EndUpdate;
end;
Variable height nodes with oversized icons

With word wrapping enabled, long text also drives the node height:

Word-wrapped variable-height nodesPascalC++
uses
  FMX.TMSFNCTreeView;

procedure TForm1.EnableWordWrap;
begin
  TreeView1.Columns[0].WordWrapping := True;
  TreeView1.NodesAppearance.HeightMode := tnhmVariable;
end;
void __fastcall TForm1::EnableWordWrap()
{
  TreeView1->Columns->Items[0]->WordWrapping = true;
  TreeView1->NodesAppearance->HeightMode = tnhmVariable;
}
Variable height nodes with wrapped text

Checkbox and radiobutton support

Each node column can display a checkbox or radiobutton independently via the CheckTypes property:

Treeview nodes advancedPascal
procedure TForm1.SetupCheckNodes;
var
  n: TTMSFNCTreeViewNode;
  I: Integer;
begin
  TreeView1.BeginUpdate;
  TreeView1.ClearNodeList;
  TreeView1.ClearNodes;
  TreeView1.ClearColumns;
  TreeView1.Columns.Add.Text := 'Checkbox / radiobutton';

  for I := 0 to 3 do
  begin
    n := TreeView1.Nodes.Add;
    n.Text[0] := 'CheckBox ' + IntToStr(I);
    n.CheckTypes[0] := tvntCheckBox;
    if Odd(I) then
      n.Checked[0] := True;
  end;

  for I := 0 to 3 do
  begin
    n := TreeView1.Nodes.Add;
    n.Text[0] := 'Radiobutton ' + IntToStr(I);
    n.CheckTypes[0] := tvntRadioButton;
    if I = 2 then
      n.Checked[0] := True;
  end;

  TreeView1.EndUpdate;
Nodes with checkboxes and radiobuttons

To use virtual mode for checkboxes, implement OnGetNodeCheckType and OnIsNodeChecked.

Toggle check state programmatically:

Toggle a node's check statePascalC++
uses
  FMX.TMSFNCTreeView;

procedure TForm1.ToggleChecks(ANode: TTMSFNCTreeViewNode;
  AVirtualNode: TTMSFNCTreeViewVirtualNode);
begin
  TreeView1.ToggleCheckNode(ANode, 0);         // collection-based
  TreeView1.CheckVirtualNode(AVirtualNode, 0); // virtual
end;
void __fastcall TForm1::ToggleChecks(TTMSFNCTreeViewNode *ANode,
  TTMSFNCTreeViewVirtualNode *AVirtualNode)
{
  TreeView1->ToggleCheckNode(ANode, 0);         // collection-based
  TreeView1->CheckVirtualNode(AVirtualNode, 0); // virtual
}

Extended nodes

An extended node spans all columns and displays text from column 0 only. Extended nodes are not selectable or editable by default; this can be changed via NodesAppearance.ExtendedSelectable and NodesAppearance.ExtendedEditable.

Use extended nodes as section headers within a flat list:

Treeview nodes advancedPascal
// Extended nodes that span all columns
procedure TForm1.SetupExtendedNodes;
var
  n, pn: TTMSFNCTreeViewNode;
  I: Integer;
begin
  TreeView1.BeginUpdate;
  TreeView1.ClearNodeList;
  TreeView1.ClearNodes;
  TreeView1.ClearColumns;
  TreeView1.Columns.Add.Text := 'Column 1';
  TreeView1.Columns.Add.Text := 'Column 2';

  pn := TreeView1.Nodes.Add;
  pn.Text[0] := 'Normal Node';

  pn := TreeView1.Nodes.Add;
  pn.Text[0] := 'Extended Group Header';
  pn.Extended := True;

  for I := 0 to 3 do
  begin
    n := TreeView1.AddNode(pn);
    if I = 1 then
    begin
      n.Text[0] := 'Sub-header ' + IntToStr(I);
      n.Extended := True;
    end
    else
    begin
      n.Text[0] := 'Normal Node Column 1 ' + IntToStr(I);
      n.Text[1] := 'Normal Node Column 2 ' + IntToStr(I);
    end;
  end;

  TreeView1.EndUpdate;
Mix of normal and extended nodes

In virtual mode, return True from OnIsNodeExtended to mark a node as extended.


NodesAppearance reference

Property Description
FixedHeight Node height when HeightMode = tnhmFixed
HeightMode tnhmFixed or tnhmVariable
VariableMinimumHeight Minimum height for variable-height nodes (default 25)
Font.Color Default node text color
Font Default node font
Fill, Stroke Default node background and border
SelectedFill, SelectedFontColor Selected state style
DisabledFill, DisabledFontColor Disabled state style
LevelIndent Pixel indent per nesting level
ShowLines Draw tree connector lines
ShowFocus Draw focus indicator
ExpandWidth, ExpandHeight Size of the expand/collapse icon area
SelectionArea tsaFull — full row, or tsaText — text only

See also

  • Modes — virtual vs collection-based approach
  • Interaction — editing nodes, filtering, sorting