PromptPlus

PromptPlus # PromptPlus ## **TreeSelect<T>** [![NuGet](https://img.shields.io/badge/NuGet-PromptPlus-blue)](https://www.nuget.org/packages/PromptPlus) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![.NET](https://img.shields.io/badge/.NET-8%20%7C%209%20%7C%2010-512BD4)](https://dotnet.microsoft.com/)

← Back to HomeNext: TreeSelect — Methods →


An expandable/collapsible hierarchy where the user browses nodes and picks one item, confirming with Enter.

TreeSelect<T> renders an arbitrary hierarchy of items of type T as a navigable tree. You build the structure explicitly — a required root, first-level nodes, and nested children — and the control decides at runtime whether each node is a container (has children) or a leaf. It expands and collapses branches lazily, filters against the full path, can restrict confirmation to leaves, and validates the choice before returning it.

☑️ Need to check several nodes at once? Use the TreeMultiSelect control — same tree model, with tri-state checkboxes.


On this page

Sub-page What you will find
Index (this page) What it is, when to use it, first examples, the method map
Methods Every fluent method — signature, parameters, defaults, and a snippet
Operations Building the model, keyboard, expand/collapse, filtering, leaf-only, validation
Styles The TreeSelectStyles regions and how to recolor them

When to use it

Use TreeSelect<T> when… Consider instead…
The data is hierarchical and the user picks one node
The user may check several nodes TreeMultiSelect
The data is a flat list Select
The data is tabular (multiple columns) TableSelect
It is a yes/no or single-key answer KeyPress / Confirm

Minimal example

using PromptPlusLibrary;

var result = PromptPlus.Controls
    .TreeSelect<string>("Pick a folder")
    .Root("Company")                       // required
    .TextSelector(n => n)                  // required
    .DefaultMatchBy((a, b) => a == b)      // required
    .Run();

if (!result.IsAborted)
    PromptPlus.Console.WriteLine($"You chose {result.Content}");

Building the tree

You add nodes explicitly. First-level nodes are children of the root; deeper nodes are added on the node objects returned to you:

using PromptPlusLibrary;

var tree = PromptPlus.Controls
    .TreeSelect<string>("Pick an item")
    .Root("Company")
    .TextSelector(n => n)
    .DefaultMatchBy((a, b) => a == b);

var eng     = tree.AddLast("Engineering");   // first-level → returns ITreeNode<string>
var backend = eng.AddLast("Backend");        // child of Engineering
backend.AddLast("API");                      // leaf
backend.AddLast("Database");                 // leaf
tree.AddLast("Sales");
tree.AddLast("HR");

var result = tree.Run();

A node with children renders as a container (expandable); a node with none renders as a leaf.


A richer example

using PromptPlusLibrary;

var tree = PromptPlus.Controls
    .TreeSelect<Node>("Pick a service", "Type to filter the full path")
    .Root(company)
    .TextSelector(n => n.Name)
    .ExtraInfo(n => n.Info)              // secondary text next to each node
    .PathSeparator('.')                 // Company.Engineering.Backend.API
    .ShowFullPath(true)                 // answer shows the full path
    .SelectLeafOnly()                   // only leaves can be confirmed
    .Filter(FilterMode.Contains)        // live filtering as the user types
    .DefaultMatchBy((a, b) => a.Id == b.Id);

BuildTree(tree);
var result = tree.Run();

This combines extra info, full-path display, leaf-only confirmation, and filtering — see Operations for how they behave together.


Method map

Grouped by purpose. Full signatures and examples are on the Methods page.

Purpose Methods
Build the tree Root, AddLast, AddFirst, AddAfter, AddBefore
Populate from a source Interaction, InteractionAsync
Node text & info TextSelector, ExtraInfo, ExtraInfoAsync
Paths & paging PathSeparator, ShowFullPath, PageSize
Filtering Filter
Confirmation rules SelectLeafOnly, PredicateSelected, PredicateSelectedAsync
Initial value Default, DefaultMatchBy
Read-only display ViewOnly
Dynamic description ChangeDescription, ChangeDescriptionAsync
History EnableHistory
Appearance & behavior Styles, Options
Run Run

Return value

TreeSelect<T> returns ResultPrompt<T?> — the single chosen node value (nullable).

Member Meaning
.Content The selected T (or null/default only when aborted — ViewOnly with no Default still returns the root node)
.IsAborted true when the user pressed Esc
var (node, aborted) = PromptPlus.Controls
    .TreeSelect<string>("Folder")
    .Root("Company").TextSelector(n => n).DefaultMatchBy((a, b) => a == b)
    .Run();
if (!aborted) PromptPlus.Console.WriteLine(node);

See also