← Back to Home • Next: MultiSelect — Operations →
Every fluent method on IMultiSelectControl<T>. Each returns the same control instance, so calls
chain in any order. Call Run last.
The factory is
PromptPlus.Controls.MultiSelect<T>(string prompt = "", string? description = null), which returnsIMultiSelectControl<T>.
Quick jump: AddItem · AddItems · AddGroupedItem · AddGroupedItems · AddSeparator · Interaction · InteractionAsync · TextSelector · TextSelectorAsync · ExtraInfo · ExtraInfoAsync · HideTipGroup · Filter · PageSize · Default · UseDefaultHistory · DefaultMatchBy · Range · PredicateChecked · PredicateCheckedAsync · ViewOnly · ChangeDescription · ChangeDescriptionAsync · EnableHistory · Styles · Options · Run
AddItemIMultiSelectControl<T> AddItem(T value, bool ischecked = false, bool disable = false)
Adds a single item. Set ischecked: true to pre-check it; set disable: true to show it grayed out
and non-selectable.
PromptPlus.Controls.MultiSelect<string>("Toppings")
.AddItem("Cheese", ischecked: true) // starts checked
.AddItem("Onions")
.AddItem("Anchovies", disable: true) // visible but not selectable
.Run();
Throws
ArgumentNullExceptionifvalueisnull.
AddItemsIMultiSelectControl<T> AddItems(IEnumerable<T> values, bool ischecked = false, bool disable = false)
Adds many items at once. ischecked: true pre-checks all of them; disable: true disables all of
them.
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(["Seattle", "London", "Tokyo"])
.Run();
AddGroupedItemIMultiSelectControl<T> AddGroupedItem(string group, T value, bool ischecked = false, bool disable = false)
Adds one item under a named group header. Pre-check it with ischecked: true.
AddGroupedItemsIMultiSelectControl<T> AddGroupedItems(string group, IEnumerable<T> values, bool ischecked = false, bool disable = false)
Adds many items under a named group header. Items keep their group as they scroll.
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddGroupedItems("North America", ["Seattle", "New York"])
.AddGroupedItems("Asia", ["Tokyo", "Singapore"])
.Run();
A hint shows the group of the focused item; hide it with
HideTipGroup. Pressing Space on a group header toggles every item in that group — see Operations.
AddSeparatorIMultiSelectControl<T> AddSeparator(SeparatorLine separatorLine = SeparatorLine.SingleLine, char? value = null)
Inserts a visual divider between items.
SeparatorLine |
Renders |
|---|---|
SingleLine |
A single-line rule (default) |
DoubleLine |
A double-line rule |
UserChar |
A row of the character passed in value |
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItem("Seattle")
.AddSeparator() // single line
.AddItem("Tokyo")
.AddSeparator(SeparatorLine.DoubleLine) // double line
.AddItem("London")
.AddSeparator(SeparatorLine.UserChar, '*')
.AddItem("Other")
.Run();
InteractionIMultiSelectControl<T> Interaction<T1>(IEnumerable<T1> items, Action<T1, IMultiSelectControl<T>> interactionAction)
Iterates a source collection and lets you add items programmatically — useful when mapping from a different shape or applying per-item logic.
PromptPlus.Controls.MultiSelect<(int id, string City, string other)>("Cities")
.Interaction(MyCities(), (row, ctrl) => ctrl.AddItem(row))
.TextSelector(row => row.City)
.Run();
InteractionAsyncIMultiSelectControl<T> InteractionAsync<T1>(IEnumerable<T1> items, Func<T1, IMultiSelectControl<T>, Task> interactionAction)
Asynchronous version of Interaction, for sources that need awaiting per item. The
returned task is awaited synchronously (blocking).
TextSelectorIMultiSelectControl<T> TextSelector(Func<T, string> value)
Sets how each item is rendered as text. By default ToString() is used (and [Display] names for
enums). Provide a selector for custom types.
PromptPlus.Controls.MultiSelect<User>("Users")
.AddItems(users)
.TextSelector(u => $"{u.Name} <{u.Email}>")
.Run();
TextSelectorAsyncIMultiSelectControl<T> TextSelectorAsync(Func<T, Task<string>> value)
Asynchronous version of TextSelector.
ExtraInfoIMultiSelectControl<T> ExtraInfo(Func<T, string?> extraInfoNode)
Shows a secondary piece of text for the focused item (return null to show nothing). It is wrapped
with the prefix/suffix from config (default ( )). It also appears in the live answer line while
navigating (not in the final checked-items summary shown after Enter) — see
Operations.
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(["Seattle", "Tokyo"])
.ExtraInfo(city => $"Length: {city.Length}")
.Run();
ExtraInfoAsyncIMultiSelectControl<T> ExtraInfoAsync(Func<T, Task<string?>> extraInfoNode)
Asynchronous version of ExtraInfo. The task is awaited synchronously each time the
cursor moves.
HideTipGroupIMultiSelectControl<T> HideTipGroup(bool value = true)
Hides the “current group” hint shown for grouped lists. Default false (hint visible).
FilterIMultiSelectControl<T> Filter(FilterMode value)
Controls live filtering as the user types.
FilterMode |
Behavior |
|---|---|
Disabled |
No filtering (default) |
Contains |
Match items containing the typed text |
StartsWith |
Match items starting with the typed text |
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(cities)
.Filter(FilterMode.StartsWith)
.Run();
When filtering is
Disabled, a printable key instead jumps to the next item starting with that character. See Operations.
PageSizeIMultiSelectControl<T> PageSize(byte value)
Rows visible at once (valid range 0–255). 0 (default) auto-computes from terminal height, reserving
lines for the header, footer, and pagination. Values above the available height are clamped.
PromptPlus.Controls.MultiSelect<string>("Cities").AddItems(cities).PageSize(8).Run();
DefaultIMultiSelectControl<T> Default(IEnumerable<T> values, bool useDefaultHistory = true)
Pre-checks every item that matches a value in values, and moves focus to the first match. When
useDefaultHistory is true and history is enabled, the last history entry is
preferred over values. Matching uses DefaultMatchBy if provided, otherwise
default equality.
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(cities)
.Default(["Tokyo", "Seattle"])
.Run();
Note the difference from
Select<T>.Default: this takes a collection of values, since multiple items can start checked.Throws
ArgumentNullExceptionifvaluesisnull.
UseDefaultHistoryIMultiSelectControl<T> UseDefaultHistory()
Initializes the checked set from the most recent history entry (when
EnableHistory is set), overriding any values supplied by Default.
Has no effect when history is not enabled.
DefaultMatchByIMultiSelectControl<T> DefaultMatchBy(Func<T, T, bool> comparer)
Custom equality used to locate the Default items (and to compare items in general) —
essential for records/classes where reference equality is not meaningful.
PromptPlus.Controls.MultiSelect<(int id, string City, string other)>("Cities")
.Interaction(MyCities(), (r, c) => c.AddItem(r))
.TextSelector(r => r.City)
.DefaultMatchBy((a, b) => a.id == b.id)
.Default([new(4, "New York", "any4")])
.Run();
Throws
ArgumentNullExceptionifcomparerisnull.
RangeIMultiSelectControl<T> Range(int minvalue, int? maxvalue = null)
Constrains how many items may be checked. minvalue is the minimum required at confirm time;
maxvalue (optional) caps the maximum. The range is enforced on Enter: too few or too many
checked keeps the list open and shows an error.
| Argument | Meaning |
|---|---|
minvalue |
Minimum items that must be checked (0 = optional) |
maxvalue |
Maximum items allowed; null (default) = no upper bound |
PromptPlus.Controls.MultiSelect<string>("Cities", "Min. 2, Max. 3")
.AddItems(["Seattle", "London", "Tokyo", "New York", "Singapore"])
.Range(2, 3)
.Run();
Throws
ArgumentOutOfRangeExceptionwhenminvalue < 0, or whenmaxvalueis specified and is less thanminvalue.
Validation runs when the user checks an item (Space). On failure the check is rejected and the list shows an error.
PredicateCheckedIMultiSelectControl<T> PredicateChecked(Func<T, bool> validselect)
IMultiSelectControl<T> PredicateChecked(Func<T, (bool, string?)> validselect)
| Overload | Return | Behavior |
|---|---|---|
Func<T, bool> |
true = valid |
Generic error on failure |
Func<T, (bool, string?)> |
(isValid, message) |
Custom message on failure |
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(["Seattle", "London", "Tokyo"])
.PredicateChecked(city => city == "Tokyo"
? (true, null)
: (false, "Only Tokyo can be selected"))
.Run();
Mass operations — toggle-all (F2) and group-header Space — silently skip items the predicate rejects rather than showing an error.
PredicateCheckedAsyncIMultiSelectControl<T> PredicateCheckedAsync(Func<T, Task<bool>> validselect)
IMultiSelectControl<T> PredicateCheckedAsync(Func<T, Task<(bool, string?)>> validselect)
Asynchronous counterparts of the two PredicateChecked overloads.
⚠️ The async predicate is awaited synchronously (blocking) on the UI thread — keep it fast.
ViewOnlyIMultiSelectControl<T> ViewOnly(bool value = true)
Renders the list for viewing only — checks cannot be changed. Combine with Default (or
AddItems(..., ischecked: true)) to show a fixed set of checked entries.
PromptPlus.Controls.MultiSelect<string>("Enabled features (read-only)")
.AddItems(["Logging", "Caching", "Metrics"], ischecked: true)
.ViewOnly()
.Run();
ChangeDescriptionIMultiSelectControl<T> ChangeDescription(Func<T, string> value)
Recomputes the description from the currently focused item as the user navigates.
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(cities)
.ChangeDescription(city => $"You are on: {city}")
.Run();
ChangeDescriptionAsyncIMultiSelectControl<T> ChangeDescriptionAsync(Func<T, Task<string>> value)
Asynchronous version of ChangeDescription.
EnableHistoryIMultiSelectControl<T> EnableHistory(string filename, Action<IHistoryOptions>? options = null)
Persists confirmed selections to filename and can restore them (via Default or
UseDefaultHistory). The IHistoryOptions builder is identical to the one
documented for Input → EnableHistory (MinPrefixLength,
MaxItems, ExpirationTime, FilterType, PageSize).
PromptPlus.Controls.MultiSelect<string>("Cities")
.AddItems(cities)
.EnableHistory("city-history", opt => opt.MaxItems(8).FilterType(FilterMode.StartsWith))
.UseDefaultHistory()
.Run();
Throws
ArgumentNullExceptioniffilenameisnull.
StylesIMultiSelectControl<T> Styles(MultiSelectStyles styleType, Style style)
Recolors one visual region of this control. See the region list and examples on the Styles page.
using PromptPlusLibrary;
using ConsolePlusLibrary; // Color, Style live here
PromptPlus.Controls.MultiSelect<string>("Cities").AddItems(cities)
.Styles(MultiSelectStyles.Selected, new Style(Color.Blue, Color.Default))
.Run();
OptionsIMultiSelectControl<T> Options(Action<IControlOptions> options)
Overrides global behaviors for this one control (prompt/description text, abort key, tooltip, hide-after-finish, extra-info affixes). See Global Behaviors → Per-Control Override.
Throws
ArgumentNullExceptionifoptionsisnull.
RunResultPrompt<T[]> Run(CancellationToken token = default)
Renders the list and blocks until the user confirms (Enter) or aborts (Esc). Returns
ResultPrompt<T[]> — the array of checked items (an empty
array when aborted or nothing was checked).
var result = PromptPlus.Controls.MultiSelect<string>("Cities").AddItems(cities).Run();
MultiSelectStyles regions