This document defines preview-era API governance and the stable 1.x
compatibility boundary. 1.0.0-preview.1 records the first public audit and
migration baseline; it does not freeze later 1.0 previews to that exact shape.
1.0.0-preview.1is the first audit, migration, and package-comparison baseline.- Source and binary compatibility with 0.9.x is intentionally not promised.
- During the 1.0 preview series, current applicable WinUI API shape is authoritative for WinUI-derived controls. Source-audited additions, changes, and removals may deliberately break an earlier preview when the same change updates the checked-in inventories, documents WPF adaptations, supplies migration guidance, and adds focused tests.
- Checked-in API/resource inventories and package validation are drift detectors. They reject accidental changes; they are deliberately rebaselined when an accepted preview-era parity change alters the public contract.
- Stable
1.0.0establishes the SemVer compatibility baseline. Within the stable 1.x line, additions remain possible, but an upstream breaking change must use a compatible ModernWpf adaptation or wait for the next ModernWpf major version.
The contract applies to all supported package targets:
net462net8.0-windows7.0net10.0-windows7.0
| Surface | Role in ModernWpf 1.x | Compatibility decision |
|---|---|---|
| Current ModernWpf | The API that ships in ModernWpf.dll and ModernWpf.Controls.dll. |
Audited against 1.0.0-preview.1 and later accepted package baselines. Preview changes may be deliberately rebaselined; stable 1.x changes follow SemVer. |
0.9.7-preview.2 |
Last public prerelease and historical migration input. | Not a compatibility baseline. It has 263 ModernWpf top-level public types; the v1 candidate has 347. The v1 set adds 117 and removes 33 relative to this release. |
0.9.6 |
Last stable public release and historical migration input. | Not a compatibility baseline. It has 261 ModernWpf top-level public types; v1 adds 119 and removes 33 relative to it. |
| Current WinUI | Primary naming, control-shape, event, sealing, and versionability authority for WinUI-derived ModernWpf controls. | Follow current applicable WinUI, including API changes during previews, unless WPF requires a documented adaptation. The adopted product epoch is microsoft-ui-xaml commit 26eb4a71, reconciled with stable winui3/release/2.4.0 and Gallery in docs/winui3-sync-2026-09-06-rc1.md; moving selectors and family mappings live in tools/upstream/upstream-sync.json. |
| Official WPF Fluent | Primary styling and behavior authority for stock WPF controls, and the platform Fluent implementation used on .NET 10. | Complements WinUI; it does not rename ModernWpf custom-control CLR APIs. Audited source is dotnet/wpf commit 7f005faa. |
The RC 1 checked-in CLR baseline contains 1,586 API entries for
ModernWpf.dll and 3,225 for ModernWpf.Controls.dll. The packaged .NET 8
assemblies expose 126 and 270 supported top-level types respectively. WPF's
generated GeneratedInternalTypeHelper is compiler infrastructure and is not
a supported ModernWpf API.
Preview 1 recorded these versionability decisions. They remain the migration starting point and are re-evaluated when current WinUI changes:
- WinRT projection implementation types are internal.
ABI.*, embedded WinRT contract markers, and other generated projection namespaces must never become package API. IconSourceis concrete and uses a protected virtual creation hook, matching current WinUI's extensible shape.FlyoutBase.CreatePresenteris virtual rather than abstract, matching the current WinUI versioning shape.- Repeater factories use the public
IElementFactory; the duplicateIElementFactoryShimsurface is removed. CommandBar.DynamicOverflowItemsChangingusesTypedEventHandler<CommandBar, DynamicOverflowItemsChangingEventArgs>.- Stale repeater animator APIs are implementation-only because the animator property is not a public current-WinUI surface.
- Public automation peers live consistently under
ModernWpf.Automation.Peers. - Caption-button pointer/pressed bookkeeping remains internal to the WPF window-shell template rather than package API.
StackLayoutexposes current WinUI's positiveIsVirtualizationEnabledproperty without the obsolete inverse alias.- Template-only converters, panels, proxies, visual helpers, and private automation peers are internal.
- WinUI runtimeclasses are sealed or unsealed to match current source unless a WPF extensibility requirement is recorded below.
Notable 0.9 migration changes include:
SimpleStackPanelis replaced by the currentStackPanelExsurface.IElementFactoryShimconsumers should implementIElementFactory.- The WPF window-shell facade and control are named
WindowTitleBarandWindowTitleBarControl; Preview 4 adds the distinct, content-oriented WinUI-shapedTitleBarcontrol. - Types under
ModernWpf.Controls.Primitivesthat existed only to service templates are no longer public.
These public names or shapes are not accidental WinUI drift:
| ModernWpf API | Reason |
|---|---|
StackPanelEx |
Avoids colliding with WPF's stock StackPanel while adding WinUI spacing and scroll-snap behavior. |
WindowTitleBar and WindowTitleBarControl |
WPF window-chrome adapter distinct from current WinUI's content-oriented TitleBar control. |
WindowBackdrop and WindowBackdropKind |
WPF attached-property adapter over DWM system backdrops, with explicit supported-OS, composition, High Contrast, and solid-brush fallbacks. |
ItemContainer.CornerRadius |
WinUI Control supplies this inherited property; WPF Control does not, so the port explicitly owns WPF's compatible Border.CornerRadiusProperty. |
ContextFlyoutService and FlyoutService |
WPF attached-property adapters for WinUI flyout ownership. |
INumberBoxNumberFormatter |
WPF-friendly formatting contract in place of WinRT number-formatting interfaces. |
ListViewBaseItem and its automation peer |
WPF realization of platform/XamlOM list-item primitives used by the WinUI control family. |
RadioMenuItem |
WPF naming adaptation of WinUI's radio menu-flyout item. |
TeachingTipClosingDeferral |
WPF replacement for Windows.Foundation.Deferral. |
BindingProxy |
WPF resource/binding bridge used by consumer XAML. |
WrapGrid |
Remains inheritable because ItemsWrapGrid derives from the WPF implementation. |
ToggleSwitch |
Remains inheritable to preserve its WPF protected customization hooks. |
NavigationViewItemAutomationPeer set-position overrides |
Exist only on WPF target frameworks whose base automation peer exposes those virtual methods; package validation tracks the per-target shape. |
The Preview 1 public interfaces are:
ICommandBarElementIElementFactoryIKeyIndexMappingINumberBoxNumberFormatterIScrollAnchorProviderIScrollControllerIScrollControllerPanningInfoIScrollSnapPointsInfo
For a ModernWpf-originated capability, add a new interface or an extensible base-class member instead of changing one of these interfaces. During previews, however, a current WinUI change to the corresponding interface is authoritative: mirror the feasible source shape, update the inventories, and document the consumer migration. After stable 1.0, preserve the shipped interface throughout 1.x or defer the upstream break to the next major version.
Only entries in these files are public XAML resource contracts:
ModernWpf/PublicResourceKeys.Shipped.txtModernWpf/PublicResourceKeys.Unshipped.txt
Each entry identifies a literal, top-level x:Key and the dictionary that
owned it in the accepted public snapshot. The Preview 1 audit baseline contains
5,320 source-qualified entries from:
ThemeResources/Light.xamlThemeResources/Dark.xamlThemeResources/HighContrast.xamlModernWpfControlsResources.xamlDensityStyles/Compact.xaml
During previews, an upstream-driven change may deliberately add, move, rename, or remove an inventoried key under the same audit, migration, and rebaseline rules as a CLR API change. After stable 1.0, these keys are part of the SemVer contract for the stable 1.x line.
The following are not public contract entries unless later added to an explicit manifest:
- Template parts
- Visual states
- Implicit or
{x:Type ...}keys - Template-local keys
- Unlisted control-template and implementation resources
Run tools/api-contracts/Update-PublicResourceKeyContract.ps1 to validate the
existing manifest and add newly chosen public keys to the unshipped file.
- Make the API change.
- Classify it as additive, a deliberate current-WinUI parity change, a
documented WPF adaptation, or an accidental change. A deliberate preview
break must cite the upstream source audit and add a
## Breaking changesmigration entry to the current release notes. - For a CLR addition or replacement, run
dotnet formatwith diagnosticRS0016, include generated source, and review the newPublicAPI.Unshipped.txtentries. Remove obsolete shipped entries only for an accepted preview break. - For a supported resource-key addition, run
tools/api-contracts/Update-PublicResourceKeyContract.ps1and review the unshipped resource entries. Update or remove an existing entry only under the deliberate-break rule. - Build every target framework and run the theme/resource tests.
- Before publishing a release candidate or an accepted package baseline, promote every accepted entry to the corresponding shipped inventory. RC builds and builds whose version equals the active package baseline require all unshipped inventories to be empty. RC 1 freezes 5,501 source-qualified resource entries and the CLR counts above without changing the combined Shipped/Unshipped surface. Surface changes after RC acceptance require a new RC and restart the unchanged 14-day soak.
- Pack the NuGet package. Strict cross-target validation always applies. When
the current version differs from
ModernWpfPackageValidationBaselineVersion, NuGet also compares with that published package. Baseline validation uses normal compatibility mode: it rejects binary breaks but permits additive APIs because additions are separately review-gated by the checked-in public API inventories. To accept a deliberate break during previews, advance that property to the current development version in the same change as the source audit, inventory updates, tests, and release-note migration entry.ModernWpfPreviewAuditBaselineVersionremains fixed at1.0.0-preview.1as the machine-readable identifier of the published historical package. It is available for explicit migration audits, but it is intentionally not the active NuGet compatibility gate. - Run
tools/release/Verify-ModernWpfPackage.ps1. It rejects namespace leaks, cross-target top-level type drift, stale XML documentation, and malformed package assets.
The analyzer treats differences from the checked-in accepted API inventories
as build errors; an intentional preview change updates those inventories rather
than suppressing the analyzer. Once stable 1.0.0 is published, do not advance
the active package baseline within 1.x to hide an incompatibility. Nullable
annotations are not yet a v1 contract because the existing codebase is
nullable-oblivious; they can be introduced as a separately reviewed contract
improvement.