This document captures the design and implementation details of NumberBox<T>.
For end-user usage and examples, see NumberBox.
Value.TextEditorCore via TextEditorBase (caret, selection, clipboard, undo/redo).Value only updates when the current text parses successfully (and optional validation succeeds).Value while allowing the user to temporarily enter invalid text.FormatProvider is set).Value, not while the user is typing).NumberBox<T> is defined as:
public partial class NumberBox<T> : TextEditorBase where T : struct, INumber<T>Bindable properties:
Value : T - the numeric value (primary binding surface).TextAlignment : TextAlignment - alignment of the text inside the editor.ShowValidationMessage : bool - whether validation messages are shown.InvalidNumberMessage : string? - message used when parsing fails.ValueFormatter : Delegator<Func<T, string>> - optional formatter used when converting Value to displayed text.ParseStyles : NumberStyles - number styles used for parsing (default NumberStyles.Number).FormatProvider : IFormatProvider? - provider used for parsing/formatting (default null).ValueValidator : Delegator<Func<T, string?>> - optional semantic validator for parsed values.Additional internal bindable property:
Text : string? - backing text for the editor (used via a DynamicTextDocument). This is intentionally internal and is
mainly for diagnostics/tests.NumberBox<T> maintains two representations:
Value : T (typed)Text : string (editable text)On text changes (user edits):
Value is not updated.T.TryParse(text, ParseStyles, FormatProvider, out parsed).InvalidNumberMessage and Value is not updated.ValueValidator (if set) runs:
null means validValue is not updatedValue is updated to the parsed value.When the control decides that Value is the source of truth, it formats Value into Text using:
ValueFormatter (if set), otherwiseIFormattable.ToString(null, FormatProvider) when supported, otherwiseValue.ToString()Key rules:
Value is treated as the source of truth even if validation is triggered by
unrelated property changes. This avoids overwriting a bound state.RenderOverride synchronizes Text from Value to keep the display current even if Value changes
through binding mechanisms that do not trigger the generated change callback.NumberBox<T> currently requests a fixed width chosen as:
width = max(10, min(availableWidth, 24))Height is:
ShowValidationMessage is trueValidationStyle.Gap) between the editor and the validation message.The final rectangle is split into:
The editor uses TextBoxStyle.Padding and calls UpdateEditorLayout(...) from the base editor infrastructure.
The editor portion uses TextBoxStyle (via GetTextBoxStyle()):
TextEditorBase)NumberBox<T> supports "overflow indicators" (left/right glyphs) when the edited text is horizontally scrolled.
TextBoxStyle.Scroll.OffsetX / Scroll.ViewportWidth / Scroll.ExtentWidthValidation is rendered using an internal ValidationMessageHost child:
ValidationMessage.ValidationStyle (not TextBoxStyle).TextBlock or Markup.NumberBox<T> inherits all text editor behaviors from TextEditorBase:
The numeric-specific logic is implemented as validation on every text change.
NumberBox<T> uses:
TextBoxStyle for the editor portion (padding, background, selection, placeholder, overflow indicators).ValidationStyle for the validation message line (padding, glyphs, colors, gap).Note: a NumberBoxStyle type exists in the codebase, but the current NumberBox<T> implementation does not consult it.
If NumberBoxStyle is intended to be the primary style surface for validation message customization, this should be wired
up in a future change (or the unused style should be removed).
Tests:
src/XenoAtom.Terminal.UI.Tests/NumberBoxInputTests.cs (parsing, validation, binding updates)src/XenoAtom.Terminal.UI.Tests/DataPresenterTests.cs (default template uses NumberBox<int> for int editor role)Demo:
samples/ControlsDemo/Demos/NumberBoxDemo.csMin/Max value clamp mode (either strict or coercing) as a first-class feature.NumberBoxStyle into the implementation (or remove it if obsolete) and add deterministic rendering tests for the
validation line and overflow indicators.