← Back to Home • Next: TableSelect — Styles →
How the TableSelect<T> control behaves while it is running: keyboard, columns, filtering, horizontal
scrolling, paging, validation, history, and view-only mode.
Select a product ← prompt
Category: Electronics ← description (optional / dynamic)
┌──────┬───────────────┬────────────┐
│ Id │ Name │ Price │ ← header row
├──────┼───────────────┼────────────┤
│ 1 │ Notebook Pro │ $ 1299.99 │ ← focused row (SelectedCell)
│ 2 │ Wireless Mouse│ $ 29.90 │
└──────┴───────────────┴────────────┘
Filter: note ← live filter text (when filtering)
Page 1/2 ← pagination
Enter: confirm Esc: cancel ← tooltip
Every region can be recolored — see Styles.
| Key | Action |
|---|---|
↑ / ↓ |
Move focus up / down (rows) |
Page Up / Page Down |
Jump one page |
Ctrl+Home / Ctrl+End |
First / last row |
Tab / Shift+Tab |
Move the focused column; wraps around at the first/last column |
Enter |
Confirm the focused row (runs validation) |
Esc |
Abort → IsAborted == true |
| Any printable character | Type to filter (when Filter is not Disabled) |
Backspace |
Edit the filter text |
F1 |
Cycle tooltip content |
Ctrl+F1 |
Show / hide the tooltip |
Disabled rows are skipped automatically as you move.
AddColumnis header-first: header text, then aFunc<T, object>selector, then optional formatter, width, alignment, and filterable flag.- Width is either fixed (
width: n) or auto-sized from the header and all cell values atRuntime. - Content that exceeds the column width is truncated with an ellipsis; the full row is still returned in
.Content.Value.
ColumnAlignment sets per-column horizontal alignment:
| Value | Effect |
|---|---|
Left |
Align cell content to the left (default) |
Right |
Align cell content to the right (typical for numbers) |
Center |
Center cell content |
Tab / Shift+Tab always move the focused column, wrapping around at the first/last column — this
works even when every column already fits on screen and nothing needs to scroll; the focused column
is always highlighted and reported in the pagination line as Col X/Y.
HorizontalScroll only changes what happens once scrolling is
actually needed (the columns don't all fit within the console width):
Full(default) — shifts the visible viewport as a full column window.Column— focuses one column at a time.
The focused column's index is returned as .Content.ColumnIndex.
LayoutModepicks the box-drawing character set:SingleBox(default),DoubleBox,SingleASCII,DoubleASCII, orNone(no borders).HideElementshides individual regions —RowSeparator,Header,ColumnSeparator,OuterBorder— and combines with|to strip several at once.HideTable.None(default) shows everything.
When Filter is Contains or StartsWith, typing narrows the visible rows in real time:
- The match is case-insensitive.
FilterTableMode.Answermatches against the answer text (TextSelector).FilterTableMode.ColumnFiltersmatches against the concatenated text of every column declared withisFilterable: true.- Matching resets paging to the first page of results.
- Clearing the filter (Backspace) restores the full list.
Disabled (the default) turns typing off entirely — arrow keys only.
Pressing Enter on the focused row:
- Validation runs —
PredicateSelected/PredicateSelectedAsync, if configured. - Valid → the control closes and returns the row inside a
TableSelectResult<T>. Invalid → the table stays open and shows the error line.
Disabled rows cannot be focused for confirmation, so validation typically guards business rules rather than availability.
Default(value)pre-selects a row; provideDefaultMatchByfor records/classes so the right row is located.- With
EnableHistory, confirmed selections are stored on disk;UseDefaultHistory(orDefault(..., useDefaultHistory: true)) restores the last one on the next run. - History options (
MinPrefixLength,MaxItems,ExpirationTime,FilterType,PageSize) match the Input history options.
ViewOnly() renders the table for display only:
- Arrow and column keys still navigate, but the selection cannot change.
- On Enter the control returns the item highlighted at startup (from
Defaultor the first row), regardless of where the user browsed. - Selection predicates and disabled-row restrictions are not enforced.
Set per instance via Options(...), or globally on
PromptPlus.Config:
| Option | Effect on TableSelect<T> |
|---|---|
EnabledAbortKey(false) |
Removes Esc — the user must choose |
HideAfterFinish(true) |
Erases the table after confirm — the whole control is erased, not just the interactive part |
ShowTooltip(false) |
Hides the keyboard hint line |
Prompt(...) / Description(...) |
Overrides the prompt / description text |
PageSize can be set per control (PageSize) or globally (PromptPlus.Config.PageSize).
- Configuration is required.
RunthrowsValidationExceptionunless at least one column and one row have been added. - Aborted results carry
.Content == default(aTableSelectResult<T>withdefault(T)). Always branch onIsAborted. - Custom types need equality. Without
DefaultMatchBy,Defaulton a record/class may not match the intended row. - Async callbacks block the UI thread — keep validators, selectors, and description callbacks fast.
- Long cells are truncated with
…; the full row is still returned in.Content.Value.
- Methods — the API these behaviors come from
- Keyboard Bindings — full physical-key reference
- Global Behaviors — the config layer behind
Options - TableMultiSelect → Operations — checkbox behavior for the multiple-row sibling