Skip to content

Support MVVM binding for WinForms, MAUI, and other UI frameworks #94

Description

@KaliCZ

Updated for v2 (#123). The Kalicz.StrongTypes.Wpf package is gone. Every strong type now carries its converter as a [TypeConverter] attribute on the type itself — ParsableTypeConverter<T> for the string-like types (NonEmptyString, Email, Digit) and the non-generic StrongTypeConverter bootstrap for the generic numeric wrappers (Positive<T> and friends). Anything that resolves converters through TypeDescriptor — WPF, WinForms, designers, PropertyGrid — now works with zero setup and no registration call. This issue tracks the frameworks that need more than that.

WPF — done

Covered by v2 with no package and no call (see the WPF section of the readme, plus the binding/culture/nullable tests). Nothing left here.

WinForms

WinForms Binding resolves converters through TypeDescriptor.GetConverter, so the on-type [TypeConverter] should be picked up with no registration — the old TypeDescriptionProvider-on-typeof(object) mechanism and the UseWPF concern are both obsolete. What's left is verification, not new plumbing:

  • Confirm the converter is invoked end-to-end with a hosted, handle-created control. The earlier experiment failed only because the TextBox had no parent Form / created handle, so bindings never activated — a test-harness lifecycle problem, not a converter one.
  • If it holds, ship a WinForms test project (STA, hosted control) as the proof, mirroring the WPF tests.

No public API is needed — there is nothing to register.

MAUI

MAUI does not route through TypeDescriptor. Microsoft.Maui.Controls.BindingExpression.TryConvert reads TypeConverterAttribute directly via reflection on the bound type and instantiates the converter itself. v2 already bakes that attribute onto every strong type, so the previously-planned "attach a [TypeConverter] via the source generator" step is done. Two things still need checking before claiming support:

  • String-like types (NonEmptyString, Email, Digit) carry [TypeConverter(typeof(ParsableTypeConverter<T>))] — a closed generic with a parameterless constructor, so MAUI's reflective Activator.CreateInstance should build it. Verify a two-way Entry.Text ↔ strong-type binding round-trips.
  • Numeric wrappers (Positive<T>, …) carry [TypeConverter(typeof(StrongTypeConverter))], and StrongTypeConverter has no parameterless constructor — it takes the closed Type, which TypeDescriptor supplies but MAUI's plain instantiation will not. These likely need a generated closed converter per numeric type (a [TypeConverter(typeof(PositiveInt32Converter))]-style shape emitted by the source generator) or a MAUI-specific registration path. This is the substantive MAUI work, and it is numeric-only.

Multi-targeting (net10.0-android / -ios / -maccatalyst / -windows10.0.x) still applies if this becomes its own package (Kalicz.StrongTypes.Maui).

WinUI 3 / WinAppSDK

Different again — a XAML markup compiler plus a WinRT type system. Its own package and validation pass; not investigated.

Avalonia

Not looked at. Should be straightforward to investigate once the WinForms / MAUI shapes are settled.

Suggested order

  1. WinForms — verification only, the smallest delta from what v2 already ships.
  2. MAUI — the string-like types likely bind as-is; the numeric-wrapper converter gap (no parameterless constructor on StrongTypeConverter) is the real piece.
  3. WinUI and Avalonia after that.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions