TimePicker
Overview
Section titled “Overview”TimePicker collapses the web contract’s five-part shell (Root/Input/Trigger/Content/Column) onto
one templated Control: PART_Input is a real embedded NaviusTimeInput bound two-way to
Value/Granularity/HourCycle/MinuteStep/SecondStep so typed edits and popup column
selections share one value with no extra glue, PART_Trigger is a ToggleButton opening a
NaviusAnchoredPopup, and each unit column (PART_HourColumn/PART_MinuteColumn/
PART_SecondColumn/PART_DayPeriodColumn) is a themed native ListBox populated from the pure
TimePickerOptionBuilder rather than a hand-rolled option/column pair.
xmlns:timePicker="clr-namespace:Navius.Wpf.Primitives.Controls.TimePicker;assembly=Navius.Wpf.Primitives"
<timePicker:NaviusTimePicker Value="{Binding AppointmentTime, Mode=TwoWay}" Granularity="minute" MinuteStep="15" />Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
Value |
TimeOnly? |
null |
NaviusTimePicker |
Two-way bindable by default. |
IsOpen |
bool |
false |
NaviusTimePicker |
Two-way bindable. |
Granularity |
string |
"minute" |
NaviusTimePicker |
"hour"/"minute"/"second"; controls which columns render. |
HourCycle |
int? |
null |
NaviusTimePicker |
12 or 24; null defaults to the culture’s short-time pattern sniff. |
MinuteStep |
int |
1 |
NaviusTimePicker |
Clamped to >= 1 when rebuilding the minute column’s options. |
SecondStep |
int |
1 |
NaviusTimePicker |
Clamped to >= 1. |
Culture |
CultureInfo? |
null (→ CultureInfo.CurrentCulture) |
NaviusTimePicker |
|
EffectiveHourCycle |
int |
- |
NaviusTimePicker |
Read-only CLR property: the resolved 12/24 in effect right now. |
IsEnabled |
- |
- |
Control |
No Disabled DP: native IsEnabled is used directly, matching the NaviusSelectBase/NaviusNumberField precedent. |
Events
Section titled “Events”| Event | Signature | Fires when |
|---|---|---|
ValueChanged |
RoutedPropertyChangedEventHandler<TimeOnly?> |
Whenever the composed value changes, from either typed input or column selection. |
OpenChanged |
RoutedPropertyChangedEventHandler<bool> |
When IsOpen changes. |
Keyboard interactions
Section titled “Keyboard interactions”| Key | Behavior |
|---|---|
Enter / Space / ArrowDown (embedded input or trigger, popup closed) |
Delegated to the embedded NaviusTimeInput’s own segment keyboard model, or opens the popup via the trigger. |
ArrowUp / ArrowDown (a column, popup open) |
Native ListBox selection navigation, one item at a time. |
Home / End (a column) |
Native ListBox jump to first/last item. |
Digit 0-9 (a column) |
Native ListBox TextSearch typeahead, kept as-is rather than the web’s custom buffer-reset Typeahead() logic; native reset timing differs slightly but functionally satisfies “type digits, jump to the matching option”. |
Enter / Space (a column item) |
Native ListBoxItem selection, which commits that unit via OnColumnSelectionChanged. |
Escape (popup open) |
Closes the popup via the inherited overlay/session dismissal, not a custom key handler in this class. |
UIA mechanism
Section titled “UIA mechanism”NaviusTimePickerAutomationPeer reports AutomationControlType.ComboBox (the same shape as
NaviusSelectAutomationPeer, since both controls are trigger+popup+value shells) plus a read-only
IValueProvider surfacing the composed HH:mm:ss text and IExpandCollapseProvider over IsOpen.
Each column is a native ListBox, so its ListBoxAutomationPeer/ListBoxItemAutomationPeer
already report SelectionPattern (the UIA analog of role="listbox"/role="option") with no
custom peer needed; roving tabindex and Up/Down/Home/End navigation come from ListBox natively.
Verified by TimePickerTests.cs: 5 [Fact] tests for TimePickerOptionBuilder, 10 [StaFact]
tests for the control (column visibility per granularity/hour-cycle, value-to-column sync both
directions, MinuteStep-driven option rebuilding, the embedded PART_Input wiring) and the
automation peer’s ComboBox type, ValuePattern, and ExpandCollapse round-trip.
Web deltas
Section titled “Web deltas”- No separate
NaviusTimePickerColumn/NaviusTimePickerOptionCLR types: each column is a themed nativeListBoxpopulated fromTimePickerOptionBuilder;ListBoxItemstands in forNaviusTimePickerOption, with roving tabindex androle="listbox"/"option"-equivalent automation coming fromListBoxnatively instead of being reimplemented. - Native
ListBoxTextSearchtypeahead is kept rather than reimplementing the web’s custom per-keystroke buffer-resetTypeahead()logic; the reset timing differs slightly (a short pause vs. per-keystroke) but functionally satisfies the same “type digits, jump to option” behavior. - The web’s
Highlighted-vs-Selectedtwo-state distinction (roving-active vs. actually-chosen unit) collapses to one state: nativeListBox/ListBoxItemselection already conflates roving-focus and the chosen value together on Arrow keys, matching the platform’s own interaction model rather than fighting it. - No
DisabledDP: nativeIsEnabledis used directly, matching theNaviusSelectBase/NaviusNumberFieldprecedent in this repo rather than the web contract’s separateDisabled boolparameter. ValuePatternon the root is a WPF-only addition (not asserted by the web contract, which relies on the DOM subtree instead): required because a template-only control otherwise exposes nothing over UIA (the M3 gate finding referenced by this family’s own parity doc).- Known residual: column keyboard behavior (Up/Down/Home/End/typeahead, Enter/Space activation) is
entirely native
ListBoxbehavior with no custom handler, so it was not independently re-tested by the M6 audit beyond confirming it is reachable and functionally correct; nativeTextSearch’s buffer-reset timing specifically was not verified bit-for-bit against the web’s custom buffer.
Captures
Section titled “Captures”The TimePicker Gallery page rendered at the pinned commit, in each theme.


