Field
Overview
Section titled “Overview”Field folds the web family’s Field/FieldLabel/FieldControl/FieldDescription/FieldItem/FieldError/
FieldValidity/Input anatomy into one push-based coordinator. Instead of cascading a FieldContext
object for descendants to pull (WPF has no cascading-parameter mechanism), NaviusField walks its
logical tree once its Content is assigned, registers the descendant control (default-filling an
empty NaviusFieldControl with a NaviusInput), wires the label’s Target, and pushes fresh
validity into every NaviusFieldError. The web’s discrete state attributes become read-only
dependency properties computed from WPF’s own bubbling Validation.Error, TextChanged, and
GotFocus/LostFocus events instead of a ported JS constraint-validation bridge.
xmlns:field="clr-namespace:Navius.Wpf.Primitives.Controls.Field;assembly=Navius.Wpf.Primitives"
<field:NaviusField FieldName="email" ValidationMode="OnBlur"> <StackPanel> <field:NaviusFieldLabel Content="Email" /> <field:NaviusFieldControl> <field:NaviusInput Text="{Binding Email, ValidatesOnNotifyDataErrors=True}" /> </field:NaviusFieldControl> <field:NaviusFieldDescription Content="We only use this to send receipts." /> <field:NaviusFieldError /> </StackPanel></field:NaviusField>Properties
Section titled “Properties”| Property | Type | Default | From | Description |
|---|---|---|---|---|
FieldName |
string |
"" |
NaviusField |
Form-field name key, matched against NaviusForm.Errors. Renamed from the web’s Name to avoid hiding FrameworkElement.Name, which x:Name/FindName rely on. |
Disabled |
bool |
false |
NaviusField |
Drives IsEnabled; combined with an enclosing NaviusFieldset’s own disabled cascade via native IsEnabled tree inheritance. |
Invalid |
bool |
false |
NaviusField |
Consumer “mark invalid” flag. Does not auto-clear. |
ServerInvalid |
bool |
false |
NaviusField |
Server-side invalidity. Auto-clears on the next descendant TextChanged. |
ValidationMode |
FieldValidationMode |
OnSubmit |
NaviusField |
OnSubmit / OnBlur / OnChange; gates when IsFieldValid/IsFieldInvalid are revealed. |
ExternalErrors |
IReadOnlyList<string>? |
null |
NaviusField |
Error messages injected by name, typically by NaviusForm.Errors. |
IsFieldValid |
bool? |
null |
NaviusField |
Read-only. Tri-state: null until Reveal()’d, matching the web’s valid: null. |
IsFieldInvalid |
bool |
false |
NaviusField |
Read-only. |
IsDirty |
bool |
false |
NaviusField |
Read-only. Set on the first descendant TextChanged. |
IsTouched |
bool |
false |
NaviusField |
Read-only. Set on the first descendant LostFocus. |
IsFilled |
bool |
false |
NaviusField |
Read-only. True when the registered TextBox’s Text is non-empty. |
IsFieldFocused |
bool |
false |
NaviusField |
Read-only. Tracks descendant GotFocus/LostFocus. |
RegisteredControl |
UIElement? |
null |
NaviusField |
CLR property (not a DP): the descendant control found or default-filled by WireDescendants. |
Content |
object |
- |
ContentControl (NaviusFieldControl) |
Hosts the field-aware control; NaviusField default-fills a NaviusInput when left empty and registers whatever ends up here. |
Target |
FrameworkElement |
null |
Label (NaviusFieldLabel) |
Wired by the ancestor NaviusField to the registered control; gives native Alt+mnemonic focus, plus an explicit PreviewMouseLeftButtonDown handler for plain-click delegation (WPF’s Label does not focus Target on a non-mnemonic click by itself). |
Content |
object |
- |
ContentControl (NaviusFieldDescription) |
Supplementary field text; NaviusField reads its string Content and applies it as AutomationProperties.HelpText on the registered control. |
Content |
object |
- |
ContentControl (NaviusFieldItem) |
Groups one item’s label + description (e.g. inside a checkbox/radio list); no field-state wiring of its own. |
Match |
string? |
null |
NaviusFieldError |
Narrows display to a specific error message string (not an HTML5 validity key); null shows whenever the field is invalid. |
ForceMatch |
bool |
false |
NaviusFieldError |
Shows unconditionally regardless of validity. |
Content |
object |
null |
ContentControl (NaviusFieldError) |
Custom error content; when null and shown, defaults to the joined error messages. |
Text |
string |
"" |
TextBox (NaviusInput) |
Inherited from TextBox; natively two-way bindable, no separate Value/DefaultValue pair is needed. |
Methods
Section titled “Methods”| Method | Description |
|---|---|
Reveal() |
Surfaces current validity per ValidationMode. Called by NaviusForm on every submit attempt (the stand-in for the web’s FieldContext.RevealAsync()); a consumer can also call it directly outside a Form. |
RegisterControl(UIElement) |
Registers an arbitrary descendant as the field’s control (used internally by WireDescendants). |
FocusRegisteredControl() |
Focuses RegisteredControl; called by NaviusForm to focus the first invalid field. |
UIA mechanism
Section titled “UIA mechanism”NaviusField ships no custom AutomationPeer. Accessible-name association happens on the
registered control, not the field wrapper: NaviusFieldLabel.Target gives native Label→control
wiring, and AutomationProperties.HelpText is applied to the registered control from the first
NaviusFieldDescription descendant’s string content (fixed in the M6 audit; previously missing
entirely). NaviusFieldError carries AutomationProperties.LiveSetting=Assertive, the UIA analog
of role="alert". The discrete state DPs (IsDirty/IsTouched/IsFilled/IsFieldFocused/
IsFieldValid/IsFieldInvalid) are computed from real bubbling WPF events rather than surfaced
attributes. The unit suite exercises this against real windows, including the M6 regression
FieldTests.FieldDescription_IsAssociatedWithControl_ViaAutomationHelpText.
Web deltas
Section titled “Web deltas”- No cascading-parameter equivalent exists in WPF:
NaviusFieldpushes to descendants onOnContentChangedinstead of parts pulling a cascadedFieldContext, deliberately avoidingFrameworkElement.Loaded, which never fires outside a live Window. - The web’s GUID id registry (
ControlId,DescribedBy, message ordering) is dropped entirely: label/description association uses element references (Label.Target,AutomationProperties.HelpText) instead offor=/aria-describedbyids. FieldValidity’s HTML5ValidityStateflag set (BadInput/PatternMismatch/StepMismatch/…) collapses to a single invalid/valid plus message-list model read off WPF’s ownValidation.GetErrors, soNaviusFieldError.Matchmatches a message string, not a validity key.NamebecameFieldName(FrameworkElement.Nameis load-bearing forx:Name/FindName).ServerInvalidauto-clears only on a descendantTextChanged: what counts as “the next edit” for non-text controls (ComboBox, DatePicker, CheckBox) stays unresolved, the same open question the web contract itself leaves open.- The
ControlProps/@attributessplat pattern (NaviusFieldControl.ChildContentcascading a custom control’s wiring) is replaced by WPF’s ordinary Content model: any control placed insideNaviusFieldControlgets registered, nothing needs to be splatted. NaviusFieldValidity(a render-prop exposing the live validity snapshot) has no separate control: consumers bind directly to the public read-only DPs instead.- Known residual (M6 audit): the label-to-control accessible-name relationship relies solely on
native
Label.Target, not an explicitAutomationProperties.LabeledBythe wayNaviusFieldsetwires it for its legend; this was not independently verified with a screen reader or UIA client. - Known residual (M6 audit): the error message is surfaced only as an assertive live region, not
also mirrored into the control’s
HelpText, so a screen reader that reads describedby/help on focus rather than the live announcement would not hear the current error. Parity of announcement with the web’saria-describedbyerror ids was not verified with assistive technology.
Captures
Section titled “Captures”The Field Gallery page rendered at the pinned commit, in each theme.


