Progress
Overview
Section titled “Overview”Progress derives from native System.Windows.Controls.ProgressBar (NaviusProgress), reusing its
PART_Track/PART_Indicator template parts and built-in IRangeValueProvider automation. It is a
non-interactive, read-only display: an out-of-range Value flips the bar to indeterminate rather
than clamping, and NaviusProgressValue/NaviusProgressLabel are companion text parts wired by
reference rather than nested content.
xmlns:navius="clr-namespace:Navius.Wpf.Primitives.Controls;assembly=Navius.Wpf.Primitives"
<StackPanel> <navius:NaviusProgressLabel x:Name="UploadLabel" Text="Upload progress" /> <navius:NaviusProgress x:Name="Upload" Value="42" Maximum="100" AutomationProperties.LabeledBy="{Binding ElementName=UploadLabel}" /> <navius:NaviusProgressValue Source="{Binding ElementName=Upload}" /></StackPanel>Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
Value |
double |
0.0 |
NaviusProgress (overrides RangeBase) |
Current value. Negative or > Maximum flips IsIndeterminate to true via a CoerceValueCallback override instead of clamping into range (“validate, don’t clamp”). NaN/Infinity are rejected outright by RangeBase’s own inherited validation before this coercion runs. |
Maximum |
double |
100.0 |
NaviusProgress (overrides RangeBase) |
A value <= 0 falls back to 100. |
IsIndeterminate |
bool |
false |
ProgressBar |
Native property; set directly or coerced to true by an out-of-range Value. |
GetValueLabel |
Func<double, double, string?>? |
null |
NaviusProgress |
Builds the value text (value, maximum) for a determinate value. Defaults to the rounded percentage. Never invoked while indeterminate. |
IsComplete |
bool |
false |
NaviusProgress |
Read-only. True when determinate and Value >= Maximum. |
IsProgressing |
bool |
computed | NaviusProgress |
Read-only, not a DP. True when determinate and Value < Maximum (!IsIndeterminate && !IsComplete). |
Source |
NaviusProgress? |
null |
NaviusProgressValue |
The progress instance whose formatted value text this element renders. |
TextOverride |
string? |
null |
NaviusProgressValue |
When set, overrides the default rounded-percentage text. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
FormatValueText() |
Returns the formatted value text: null while indeterminate, otherwise GetValueLabel or the default rounded percentage. |
Events
Section titled “Events”| Event | Signature | Fires when |
|---|---|---|
StateChanged |
RoutedEventHandler |
Value, Maximum, or IsIndeterminate changes; consumed by NaviusProgressValue to refresh its text. |
UIA mechanism
Section titled “UIA mechanism”NaviusProgressAutomationPeer (derives ProgressBarAutomationPeer) overrides GetItemStatusCore()
to return FormatValueText(), since the base peer has no first-class value-text slot.
AutomationControlType stays the inherited ProgressBar value, and the native IRangeValueProvider
(min/max/current) continues to work unmodified. The unit suite covers the coercion rule
(Value_AboveMaximum_BecomesIndeterminateWithoutClamping, Value_Negative_BecomesIndeterminate,
Value_ReenteringValidRange_ClearsIndeterminate), the NaN/Infinity rejection
(Value_NaN_IsRejectedByNativeValidation), the Maximum <= 0 fallback, and the automation peer’s
ItemStatus text.
Web deltas
Section titled “Web deltas”- “Validate, don’t clamp” is preserved via a
CoerceValueCallbackoverride onValuerather than a clamp, deliberately replacingRangeBase’s default clamp-to-range coercion. NaN/Infinityare not reachable at all:RangeBase.ValueProperty’s own inheritedValidateValueCallbackrejects them with anArgumentExceptionbeforeNaviusProgress’s coercion ever runs; only negative/> Maximumvalues are portable to the “becomes indeterminate” path.GetValueLabelisFunc<double, double, string?>?(a non-nullablevalueparameter) rather than the web contract’sFunc<double?, double, string?>?, since there is no nullable-value state to pass through at this layer.aria-labelledby/HasLabelpush-based registration is replaced by the native WPF idiom: a consumer setsAutomationProperties.LabeledByon theNaviusProgress, pointing at aNaviusProgressLabel, rather than a label registering itself with a cascaded context.NaviusProgressValueis a companion element wired via an explicitSourceproperty (not nested content or a visual-tree ancestor lookup), sinceProgressBarhas no content model to nest a value part inside.- Known residual (M6 audit): while
IsIndeterminateis true, the inheritedProgressBarAutomationPeerstill surfaces aRangeValue.Valueto UIA, whereas the web contract omitsaria-valuenowentirely in the indeterminate state. This is not claimed as fixed anywhere in the implementation notes, so it is a genuine unfixed parity gap in the UIA surface, not a false claim.
Captures
Section titled “Captures”The Progress Gallery page rendered at the pinned commit, in each theme.


