Rating
Overview
Section titled “Overview”Rating is a lookless Control owning the authoritative decimal? value plus a transient
hover-preview value; it builds Max NaviusRatingItem stars into a PART_ItemsHost panel and
drives selection, hover, and roving tabindex centrally, the same root-owns-children shape
NaviusRadioGroup uses for its items. Step/clamp/select math is factored into the pure,
unit-tested NaviusRatingMath.
xmlns:navius="clr-namespace:Navius.Wpf.Primitives.Controls;assembly=Navius.Wpf.Primitives"
<navius:NaviusRating x:Name="Stars" Value="{Binding Score, Mode=TwoWay}" Max="5" AllowHalf="True" />Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
Value |
decimal? |
null |
NaviusRating |
Controlled value; null = unrated. Kept exact-parity decimal? (not double?) so AllowHalf’s 0.5-step snapping stays exact. Two-way bindable via a Binding. |
Max |
int |
5 |
NaviusRating |
Number of visual stars, coerced to >= 1. Changing it rebuilds the star items. |
AllowHalf |
bool |
false |
NaviusRating |
Enables half-star pointer zones and 0.5 keyboard steps. |
AllowClear |
bool |
true |
NaviusRating |
Re-selecting the current value, or arrowing/Backspace/Delete below the lowest star, clears to unrated. |
ReadOnly |
bool |
false |
NaviusRating |
Focusable but non-editable; HandleKey, SelectItem, and pointer selection all no-op. |
Required |
bool |
false |
NaviusRating |
Drives ISelectionProvider.IsSelectionRequired on the automation peer. |
Invalid |
bool |
false |
NaviusRating |
Exposed for API parity; no further wiring beyond the dependency property itself. |
Label |
Func<decimal, string>? |
null |
NaviusRating |
Accessible-name factory per star value; falls back to NaviusRating.DefaultLabel (“1 star” singular, “N stars” otherwise). |
Index |
int |
1 |
NaviusRatingItem |
1-based position, pushed by the owning NaviusRating’s registration order via SetCurrentValue, not set directly by the consumer. |
FillState |
NaviusRatingFillState |
Empty |
NaviusRatingItem |
Empty / Half / Full, computed and pushed by the owner from the effective (hover-or-committed) value. |
IsHighlighted |
bool |
false |
NaviusRatingItem |
true while under the group’s hover preview. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
HandleKey(Key) |
Public, not the more natural internal, so the full keyboard table is directly unit-testable without constructing real KeyEventArgs. Returns whether the key was consumed. |
Events
Section titled “Events”| Event | Signature | Fires when |
|---|---|---|
ValueChanged |
RoutedPropertyChangedEventHandler<decimal?> |
Value changes via click, keyboard edit, or programmatic set. |
SelectRequested (item) |
EventHandler<NaviusRatingSelectEventArgs> |
A star is clicked; bubbles to the owning NaviusRating, which resolves half-vs-whole selection from IsHalf. |
HoverChanged (item) |
EventHandler<NaviusRatingSelectEventArgs> |
Pointer enters/leaves a star; IsHalf is null on leave, clearing the hover preview. |
Keyboard interactions
Section titled “Keyboard interactions”| Key | Behavior |
|---|---|
ArrowUp, ArrowRight (ArrowLeft under rtl) |
Increase by Step (0.5 with AllowHalf, else 1), clamped to Max. |
ArrowDown, ArrowLeft (ArrowRight under rtl) |
Decrease by Step; clears to unrated when AllowClear and the result would fall below Step, otherwise floors at Step. |
| Home | Jump to 1. |
| End | Jump to Max. |
| Backspace / Delete | Clear to unrated when AllowClear, otherwise no-op. |
Digit 1-9 |
Jump directly to that value, clamped to Max. |
| Space / Enter | Selects the roving-focused star (FocusIndex(Value, Max)); re-selecting the current value clears it when AllowClear. Fixed by the M6 audit, see Web deltas. |
All keyboard handling no-ops when Disabled or ReadOnly; focus moves to the star holding the
new value after every edit.
UIA mechanism
Section titled “UIA mechanism”NaviusRatingAutomationPeer (FrameworkElementAutomationPeer + ISelectionProvider) reports
AutomationControlType.Group, the same choice NaviusRadioGroupAutomationPeer makes since WPF
has no built-in radiogroup-of-buttons peer; GetSelection() resolves the currently focused
star. NaviusRatingItemAutomationPeer (+ ISelectionItemProvider) reports
AutomationControlType.RadioButton and overrides GetNameCore() to announce the real fractional
Value when the item is the checked star, or its own whole Index otherwise, via a single peer
override rather than per-star peer subclasses. The unit suite exercises HandleKey for every
table entry (including RTL mirroring), the Space/Enter fix below, and the automation peers’
selection/name behavior.
Web deltas
Section titled “Web deltas”- Confirmed fixed by the M6 audit: Space/Enter were silently unhandled in
NaviusRating.HandleKey, sinceNaviusRatingItemis a plainControl, not a native button, so nothing wired the contract’s “native button-click semantics” activation. Fixed by adding explicit Space/Enter cases toHandleKeythat select the roving-focused star. ChildContent(a custom star glyph slot on the web) is dropped: the star is a single fixedPathGeometryinThemes/Rating.xaml, styleable but not swappable per-instance without editing the template.Name(a hidden bubble input for form submission) andDir(an explicit reading-direction string) are not present onNaviusRating; the port readsFlowDirectiondirectly (isRtl = FlowDirection == FlowDirection.RightToLeft) rather than exposing aDirproperty. This is a discrepancy against the parity doc’s web-contract parameter table, which lists both: the siblingNaviusRadioGroup/NaviusToggleGroupin this same batch do expose aDirstring alongside aFlowDirectionfallback, butNaviusRating’s shipped code has neither aNamenor aDirdependency property. Found during manifest extraction; not called out in the parity doc’s own “WPF implementation notes”.- Hover preview uses
OnMouseEnter/OnMouseLeave(notPreviewMouseMove) plus a bubblingHoverChangedrouted event, the same bubble-to-owner shapeNaviusRadioGroupuses forOnItemChecked. - Residual noted then resolved during the M6 RTL wave: the half-fill visual’s
Clipwas previously flagged as not RTL-mirrored; pixel-rendered verification showed WPF’sFlowDirectionmirroring already reflects it correctly, so no residual remains for the fill clip. Keyboard arrow mirroring underrtlwas already correct throughout. Attributessplat and the hidden<input>form mirror are dropped; no WPF form-submission model.
Captures
Section titled “Captures”The Rating Gallery page rendered at the pinned commit, in each theme.


