Back to Wpfui

Logical Architecture

docs/architecture/views/logical-architecture.md

4.3.029.2 KB
Original Source

Logical Architecture

This document describes the logical architecture of WPF UI v4.2.0, a C# WPF control library implementing Microsoft Fluent Design System. It covers module dependencies, internal layer organization, control authoring patterns, cross-cutting concerns, and the multi-targeting strategy.


1. Module/Package Dependency Diagram

The WPF UI solution consists of ten projects organized around a core library (Wpf.Ui) with satellite packages for optional functionality.

mermaid
graph TD
    Abstractions["<b>Wpf.Ui.Abstractions</b>
NuGet: WPF-UI.Abstractions
Zero-dependency interfaces:
INavigationViewPageProvider,
INavigationAware, INavigableView&lt;T&gt;
<i>Targets: netstandard2.0/2.1,
net462, net8.0, net9.0, net10.0</i>"]

    Core["<b>Wpf.Ui</b>
NuGet: WPF-UI
77+ controls, theming, services,
Win32 interop
<i>Targets: net10.0-windows,
net9.0/8.0-windows,
net481, net472, net462</i>"]

    DI["<b>Wpf.Ui.DependencyInjection</b>
NuGet: WPF-UI.DependencyInjection
MS DI integration
<i>Targets: netstandard2.0/2.1,
net462, net8.0, net9.0, net10.0</i>"]

    Tray["<b>Wpf.Ui.Tray</b>
NuGet: WPF-UI.Tray
System tray icons via Shell32
<i>Targets: net10.0/9.0/8.0-windows,
net481, net472, net462</i>"]

    Syntax["<b>Wpf.Ui.SyntaxHighlight</b>
NuGet: WPF-UI.SyntaxHighlight
Code syntax highlighting (WIP)
<i>Targets: net10.0/9.0/8.0-windows,
net481, net472, net462</i>"]

    Toast["<b>Wpf.Ui.ToastNotifications</b>
NuGet: WPF-UI.ToastNotifications
Toast notifications (STUB,
all throw NotImplementedException)
<i>Targets: net10.0/9.0/8.0-windows,
net481, net472, net462</i>"]

    Gallery["<b>Wpf.Ui.Gallery</b>
Demo/showcase app
MVVM with CommunityToolkit.Mvvm
<i>Target: net10.0-windows10.0.26100.0</i>"]

    FlaUI["<b>Wpf.Ui.FlaUI</b>
NuGet: WPF-UI.FlaUI
Test automation helpers
<i>Targets: net10.0/9.0/8.0-windows,
net481</i>"]

    FontMapper["<b>Wpf.Ui.FontMapper</b>
Build tool: icon enum generation
from FluentSystemIcons JSON
<i>Target: net10.0</i>"]

    Extension["<b>Wpf.Ui.Extension</b>
VS 2022 VSIX extension
Project templates (Blank, Compact, Fluent)
<i>Target: net481 (VSIX SDK)</i>"]

    %% Dependency arrows (arrow points from dependent to dependency)
    Core --> Abstractions
    DI --> Abstractions
    DI -.->|"Microsoft.Extensions.
DependencyInjection.Abstractions 3.1.0"| ExtDI["Microsoft.Extensions.
DependencyInjection"]
    Tray --> Core
    Syntax --> Core
    Gallery --> Core
    Gallery --> DI
    Gallery --> Tray
    Gallery --> Syntax
    Gallery --> Toast

    style Abstractions fill:#e1f5ff,stroke:#0277bd
    style Core fill:#fff4e1,stroke:#f57f17
    style DI fill:#e8f5e9,stroke:#2e7d32
    style Tray fill:#e8f5e9,stroke:#2e7d32
    style Syntax fill:#e8f5e9,stroke:#2e7d32
    style Toast fill:#fff9c4,stroke:#f9a825
    style Gallery fill:#fce4ec,stroke:#c62828
    style FlaUI fill:#f3e5f5,stroke:#6a1b9a
    style FontMapper fill:#f3e5f5,stroke:#6a1b9a
    style Extension fill:#f3e5f5,stroke:#6a1b9a
    style ExtDI fill:#e0e0e0,stroke:#616161

Dependency rules:

PackageDirect dependencies
Wpf.Ui.AbstractionsNone (zero external dependencies)
Wpf.UiWpf.Ui.Abstractions, Microsoft.Windows.CsWin32 (build-time), System.Memory
Wpf.Ui.DependencyInjectionWpf.Ui.Abstractions, Microsoft.Extensions.DependencyInjection.Abstractions 3.1.0
Wpf.Ui.TrayWpf.Ui, System.Drawing.Common
Wpf.Ui.SyntaxHighlightWpf.Ui
Wpf.Ui.ToastNotificationsNone (standalone stub)
Wpf.Ui.GalleryWpf.Ui, Wpf.Ui.DependencyInjection, Wpf.Ui.Tray, Wpf.Ui.SyntaxHighlight, Wpf.Ui.ToastNotifications, CommunityToolkit.Mvvm, Microsoft.Extensions.Hosting
Wpf.Ui.FlaUIFlaUI.Core
Wpf.Ui.FontMapperNone
Wpf.Ui.ExtensionVSIX SDK (VS 2022), template projects (Blank, Compact, Fluent)

2. Core Library Internal Structure (Layer Diagram)

The src/Wpf.Ui/ project is organized into six logical layers, from user-facing controls down to Win32 primitives.

mermaid
graph TB
    subgraph "Layer 1 - Controls (77 control folders)"
        direction LR
        C1["FluentWindow"]
        C2["NavigationView"]
        C3["TitleBar"]
        C4["ContentDialog"]
        C5["NumberBox"]
        C6["AutoSuggestBox"]
        C7["ToggleSwitch"]
        C8["Snackbar"]
        C9["...70 more"]
    end

    subgraph "Layer 2 - Appearance / Theming"
        direction LR
        T1["ApplicationThemeManager
(static)"]
        T2["ApplicationAccentColorManager
(static)"]
        T3["SystemThemeWatcher
(static)"]
        T4["WindowBackgroundManager
(static)"]
        T5["ResourceDictionaryManager
(internal)"]
    end

    subgraph "Layer 3 - Services"
        direction LR
        S1["NavigationService"]
        S2["ContentDialogService"]
        S3["SnackbarService"]
        S4["ThemeService"]
        S5["TaskBarService"]
    end

    subgraph "Layer 4 - Infrastructure"
        direction LR
        I1["Converters/
18 IValueConverters"]
        I2["Extensions/
14 extension classes"]
        I3["Markup/
ControlsDictionary,
ThemesDictionary,
SymbolIconExtension,
FontIconExtension"]
        I4["Animations/
TransitionAnimationProvider"]
        I5["Input/
IRelayCommand,
RelayCommand&lt;T&gt;"]
        I6["Hardware/
DPI, rendering tier"]
        I7["AutomationPeers/
Accessibility"]
    end

    subgraph "Layer 5 - Win32 Interop"
        direction LR
        W1["CsWin32
(NativeMethods.txt
-> Windows.Win32)"]
        W2["Interop/
UnsafeNativeMethods.cs
PInvoke.cs"]
        W3["Win32/
Utilities.cs
OS version detection"]
    end

    subgraph "Layer 6 - Resources"
        direction LR
        R1["Theme/
Light.xaml, Dark.xaml,
HC1, HC2, HCBlack,
HCWhite"]
        R2["Fonts/
FluentSystemIcons-Filled.ttf
FluentSystemIcons-Regular.ttf"]
        R3["Root resources:
Accent.xaml, Palette.xaml,
StaticColors.xaml,
Typography.xaml,
Variables.xaml"]
        R4["Wpf.Ui.xaml
(master dictionary,
merges all 77 control styles)"]
    end

    C1 & C2 & C3 & C4 & C5 & C6 & C7 & C8 --> T1 & T2
    C1 & C2 & C3 --> W2
    T1 & T2 & T3 & T4 --> T5
    T3 --> W2
    T4 --> W2
    S1 --> C2
    S2 --> C4
    S3 --> C8
    S5 --> W2
    I4 --> I6
    W2 --> W1
    W2 --> W3
    T5 --> R1

    style C1 fill:#fff4e1,stroke:#f57f17
    style C2 fill:#fff4e1,stroke:#f57f17
    style C3 fill:#fff4e1,stroke:#f57f17
    style C4 fill:#fff4e1,stroke:#f57f17
    style C5 fill:#fff4e1,stroke:#f57f17
    style C6 fill:#fff4e1,stroke:#f57f17
    style C7 fill:#fff4e1,stroke:#f57f17
    style C8 fill:#fff4e1,stroke:#f57f17
    style C9 fill:#fff4e1,stroke:#f57f17
    style T1 fill:#e8f5e9,stroke:#2e7d32
    style T2 fill:#e8f5e9,stroke:#2e7d32
    style T3 fill:#e8f5e9,stroke:#2e7d32
    style T4 fill:#e8f5e9,stroke:#2e7d32
    style T5 fill:#e8f5e9,stroke:#2e7d32
    style S1 fill:#e1f5ff,stroke:#0277bd
    style S2 fill:#e1f5ff,stroke:#0277bd
    style S3 fill:#e1f5ff,stroke:#0277bd
    style S4 fill:#e1f5ff,stroke:#0277bd
    style S5 fill:#e1f5ff,stroke:#0277bd
    style W1 fill:#ffebee,stroke:#c62828
    style W2 fill:#ffebee,stroke:#c62828
    style W3 fill:#ffebee,stroke:#c62828
    style R1 fill:#f3e5f5,stroke:#6a1b9a
    style R2 fill:#f3e5f5,stroke:#6a1b9a
    style R3 fill:#f3e5f5,stroke:#6a1b9a
    style R4 fill:#f3e5f5,stroke:#6a1b9a

Layer Details

Layer 1 -- Controls (77 control folders)

Each control follows a folder-per-control pattern: Controls/{Name}/{Name}.cs + Controls/{Name}/{Name}.xaml.

Controls extend WPF base classes (ContentControl, Control, Button, ToggleButton, Window, etc.) and optionally implement WPF UI interfaces: IAppearanceControl (accent/appearance support), IIconControl (icon support), IThemeControl (theme awareness), IDpiAwareControl (DPI awareness).

Complex controls are split into partial classes by concern. For example, NavigationView spans six partial files:

FileResponsibility
NavigationView.Base.csCore logic, constructor, static constructor
NavigationView.Properties.csDependencyProperty registrations
NavigationView.Events.csRoutedEvent registrations
NavigationView.Navigation.csPage navigation logic
NavigationView.TemplateParts.csTemplate part bindings (OnApplyTemplate)
NavigationView.AttachedProperties.csAttached property definitions

Key controls: FluentWindow, NavigationView, TitleBar, ContentDialog, NumberBox, AutoSuggestBox, ToggleSwitch, Snackbar, BreadcrumbBar, InfoBar, RatingControl, ProgressRing.

Layer 2 -- Appearance/Theming

ClassPatternResponsibility
ApplicationThemeManagerStaticRuntime theme switching via ResourceDictionary swap. Fires ThemeChangedEvent.
ApplicationAccentColorManagerStaticUpdates 20+ dynamic color resources (SystemAccentColor, AccentFillColorDefault, etc.) from WinRT UISettings or registry fallback.
SystemThemeWatcherStaticHooks WndProc for WM_THEMECHANGED, WM_DWMCOLORIZATIONCOLORCHANGED, WM_SYSCOLORCHANGE. Auto-syncs app theme with OS.
WindowBackgroundManagerStaticApplies DWM backdrop effects (Mica, Acrylic, Tabbed) via DwmSetWindowAttribute.
ResourceDictionaryManagerInternalURI-based dictionary search and swap within Application.Resources.MergedDictionaries.

Six theme files: Light.xaml, Dark.xaml, HC1.xaml, HC2.xaml, HCBlack.xaml, HCWhite.xaml.

Layer 3 -- Services

Service implementations are defined at the src/Wpf.Ui/ root level alongside their interface files.

ServiceInterfaceWraps
NavigationServiceINavigationServiceINavigationView control
ContentDialogServiceIContentDialogServiceContentDialog control
SnackbarServiceISnackbarServiceSnackbar control
ThemeServiceIThemeServiceApplicationThemeManager static class
TaskBarServiceITaskBarServiceCOM ITaskbarList4 via Win32 interop

Layer 4 -- Infrastructure

ComponentContents
Converters/18 IValueConverter implementations: BoolToVisibilityConverter, BrushToColorConverter, EnumToBoolConverter, IconSourceElementConverter, CornerRadiusSplitConverter, ProgressThicknessConverter, etc.
Extensions/14 extension method classes: ColorExtensions, FrameExtensions, NavigationServiceExtensions, SnackbarServiceExtensions, SymbolExtensions, UiElementExtensions, etc.
Markup/XAML markup extensions: ControlsDictionary, ThemesDictionary, SymbolIconExtension, FontIconExtension, ImageIconExtension, ThemeResourceExtension, Design.
Animations/TransitionAnimationProvider (applies FadeIn, SlideBottom, SlideRight, etc.), Transition enum, AnimationProperties. Checks HardwareAcceleration.RenderingTier before animating.
Input/IRelayCommand, IRelayCommand<T>, RelayCommand<T> -- lightweight command implementations.
Hardware/DpiHelper, DisplayDpi, HardwareAcceleration, RenderingTier -- DPI detection and rendering tier evaluation.
AutomationPeers/CardControlAutomationPeer, ContentDialogAutomationPeer. Controls with automation peers override OnCreateAutomationPeer().
Taskbar/TaskbarProgress, TaskbarProgressState -- Windows taskbar progress bar manipulation.

Layer 5 -- Win32 Interop

A three-layer architecture for native Windows API access:

  1. CsWin32 auto-generation (NativeMethods.txt lists 35 Win32 functions/types). The Microsoft.Windows.CsWin32 source generator produces P/Invoke signatures in the Windows.Win32 namespace. Covers DWM (DwmSetWindowAttribute, DwmIsCompositionEnabled), User32 (SetWindowLong, GetDpiForWindow, GetForegroundWindow), Shell32 (ITaskbarList4), and associated structs/enums.

  2. Managed wrappers (Interop/):

    • UnsafeNativeMethods.cs -- safe wrappers with handle validation (IntPtr.Zero check + PInvoke.IsWindow) before calling CsWin32-generated methods. Methods like ApplyWindowCornerPreference, ApplyBorderColor, RemoveWindowTitlebarContents.
    • PInvoke.cs -- manual [DllImport] for SetWindowLongPtr (not generated by CsWin32 for all overloads).
    • UnsafeReflection.cs -- type casting helpers for enum-to-Win32-struct conversion.
  3. OS utilities (Win32/):

    • Utilities.cs -- OS version detection (Vista, Windows 7, 8, 10, 11 build checks), DWM composition availability, system theme detection via IUISettings3 COM interface.

Layer 6 -- Resources

PathContents
Resources/Theme/6 XAML theme dictionaries (Light, Dark, HC1, HC2, HCBlack, HCWhite)
Resources/Fonts/FluentSystemIcons-Filled.ttf, FluentSystemIcons-Regular.ttf (embedded resources)
Resources/Accent.xamlDynamic accent color resources
Resources/Palette.xamlFluent Design color palette
Resources/StaticColors.xamlNon-theme-dependent color constants
Resources/Typography.xamlFont family, size, and weight resources
Resources/Variables.xamlCorner radius, spacing, sizing tokens
Resources/Wpf.Ui.xamlMaster ResourceDictionary that merges all 77+ control style dictionaries
Resources/DefaultContextMenu.xamlStyled context menu for TextBox-like controls
Resources/DefaultFocusVisualStyle.xamlFluent focus visual style

3. Control Architecture Pattern

The following class diagram shows how WPF UI controls extend WPF base classes, implement marker interfaces, and register DependencyProperties.

mermaid
classDiagram
    direction TB

    namespace System.Windows.Controls {
        class WpfControl["Control"]
        class WpfContentControl["ContentControl"]
        class WpfButton["Button"]
        class WpfToggleButton["ToggleButton"]
        class WpfWindow["Window"]
    }

    namespace Wpf.Ui.Controls {
        class IAppearanceControl {
            <<interface>>
            +ControlAppearance Appearance
        }
        class IIconControl {
            <<interface>>
            +IconElement? Icon
        }
        class IThemeControl {
            <<interface>>
            +ApplicationTheme ApplicationTheme
        }
        class IDpiAwareControl {
            <<interface>>
            +DisplayDpi CurrentWindowDisplayDpi
        }

        class Button {
            +DependencyProperty IconProperty$
            +DependencyProperty AppearanceProperty$
            +DependencyProperty MouseOverBackgroundProperty$
            +DependencyProperty PressedBackgroundProperty$
            +DependencyProperty CornerRadiusProperty$
            +IconElement? Icon
            +ControlAppearance Appearance
            +CornerRadius CornerRadius
        }

        class FluentWindow {
            +DependencyProperty WindowCornerPreferenceProperty$
            +DependencyProperty WindowBackdropTypeProperty$
            +DependencyProperty ExtendsContentIntoTitleBarProperty$
            +WindowCornerPreference WindowCornerPreference
            +WindowBackdropType WindowBackdropType
            +bool ExtendsContentIntoTitleBar
            -static FluentWindow() DefaultStyleKeyProperty.OverrideMetadata()
        }

        class ToggleSwitch {
            +DependencyProperty OffContentProperty$
            +DependencyProperty OnContentProperty$
            +object? OffContent
            +object? OnContent
            -static ToggleSwitch() DefaultStyleKeyProperty.OverrideMetadata()
        }

        class NavigationView {
            <<partial>>
            .Base.cs: Core logic
            .Properties.cs: DependencyProperty defs
            .Events.cs: RoutedEvent defs
            .Navigation.cs: Page navigation
            .TemplateParts.cs: Template bindings
            .AttachedProperties.cs: Attached props
        }

        class ContentDialog {
            +ShowAsync() Task~ContentDialogResult~
            +Hide() void
        }
    }

    WpfButton <|-- Button
    WpfWindow <|-- FluentWindow
    WpfToggleButton <|-- ToggleSwitch
    WpfControl <|-- NavigationView
    WpfContentControl <|-- ContentDialog

    Button ..|> IAppearanceControl
    Button ..|> IIconControl

Control Authoring Recipe

Every WPF UI control follows a consistent authoring pattern:

1. C# class file (Controls/{Name}/{Name}.cs):

csharp
// All controls use the flat namespace Wpf.Ui.Controls
// regardless of their folder location (ReSharper CheckNamespace suppressed)
namespace Wpf.Ui.Controls;

public class MyControl : System.Windows.Controls.ContentControl, IAppearanceControl, IIconControl
{
    // DependencyProperty registration via static readonly fields
    public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
        nameof(Icon), typeof(IconElement), typeof(MyControl),
        new PropertyMetadata(null, null, IconElement.Coerce));

    // CLR property wrapper with [Bindable] and [Category] attributes
    [Bindable(true)]
    [Category("Appearance")]
    public IconElement? Icon
    {
        get => (IconElement?)GetValue(IconProperty);
        set => SetValue(IconProperty, value);
    }

    // Static constructor: override DefaultStyleKey for implicit style resolution
    static MyControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(MyControl),
            new FrameworkPropertyMetadata(typeof(MyControl)));
    }
}

2. XAML style file (Controls/{Name}/{Name}.xaml):

xml
<ResourceDictionary ...>
    <Style TargetType="{x:Type controls:MyControl}">
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />
        <!-- DynamicResource for all theme-dependent brushes -->
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type controls:MyControl}">
                    <!-- Template definition -->
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

3. Registration in master dictionary (Resources/Wpf.Ui.xaml):

xml
<ResourceDictionary.MergedDictionaries>
    <!-- ...other controls... -->
    <ResourceDictionary Source="pack://application:,,,/Wpf.Ui;component/Controls/MyControl/MyControl.xaml" />
</ResourceDictionary.MergedDictionaries>

Key invariants:

  • OverridesDefaultStyle="True" and SnapsToDevicePixels="True" are set on every control style.
  • Theme-dependent brushes always use DynamicResource (not StaticResource) so they update when themes switch at runtime.
  • The static constructor calling DefaultStyleKeyProperty.OverrideMetadata ensures WPF resolves the implicit style from the control's assembly rather than the application.
  • Complex controls split into partial classes by concern (properties, events, navigation logic, template parts).

4. Key Cross-Cutting Patterns

Flat Namespace

All controls reside in the single namespace Wpf.Ui.Controls despite being organized into individual subfolders under Controls/. This is enforced via // ReSharper disable once CheckNamespace pragmas in each file. The project does not suppress IDE0130 (namespace does not match folder structure) at the project level; instead, the ReSharper-specific pragma handles it.

Rationale: Consumers use a single xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml" namespace in XAML. A flat C# namespace mirrors the flat XAML namespace.

Static Singleton Managers for Theming

The four core theming classes (ApplicationThemeManager, ApplicationAccentColorManager, SystemThemeWatcher, WindowBackgroundManager) are all static classes. They operate on Application.Current.Resources directly.

Trade-off: This sacrifices testability and multi-window isolation in favor of a simple, discoverable API. Consumers call ApplicationThemeManager.Apply(ApplicationTheme.Dark) without needing DI or service resolution. The ThemeService wraps these statics behind IThemeService for consumers who prefer DI.

The Gallery demo app and sample applications use CommunityToolkit.Mvvm source generators:

  • [ObservableProperty] for bindable properties
  • [RelayCommand] for ICommand implementations
  • ViewModels extend ObservableObject and implement INavigationAware
  • Pages implement INavigableView<TViewModel> for view-model association

This is a consumption pattern only; the core Wpf.Ui library has no dependency on CommunityToolkit.Mvvm.

Central Package Management

All NuGet package versions are declared in Directory.Packages.props at the repository root. Individual .csproj files reference packages without version numbers. This ensures consistent versions across all projects in the solution.

Service Interface Inversion

Service interfaces (INavigationService, IContentDialogService, etc.) are defined at the Wpf.Ui assembly root level, alongside their implementations. This allows:

  1. Direct instantiation for simple apps: var service = new NavigationService();
  2. DI registration for hosted apps: services.AddSingleton<INavigationService, NavigationService>();
  3. The ControlsServices.Initialize(IServiceProvider) static method enables control-level service resolution.

Async Dialog Pattern

ContentDialog.ShowAsync() returns Task<ContentDialogResult> using TaskCompletionSource to bridge the WPF event model to async/await. Supports CancellationToken and closing cancellation via ContentDialogClosingEventArgs.Cancel = true.

Win32 Interop Layering

Native Windows API calls follow a strict three-layer pipeline:

NativeMethods.txt  -->  CsWin32 source generator  -->  Windows.Win32 namespace (auto-generated)
                                                              |
                                                    Interop/UnsafeNativeMethods.cs (handle validation)
                                                              |
                                                    Win32/Utilities.cs (OS version guards)

Manual [DllImport] in Interop/PInvoke.cs supplements CsWin32 for signatures it cannot generate (e.g., SetWindowLongPtr with nint parameters).


5. Target Framework Matrix

mermaid
gantt
    title Target Framework Coverage by Module
    dateFormat X
    axisFormat %s

    section Wpf.Ui.Abstractions
    netstandard2.0   :a1, 0, 1
    netstandard2.1   :a2, 1, 2
    net462           :a3, 2, 3
    net8.0           :a4, 3, 4
    net9.0           :a5, 4, 5
    net10.0          :a6, 5, 6

    section Wpf.Ui
    net462           :b1, 0, 1
    net472           :b2, 1, 2
    net481           :b3, 2, 3
    net8.0-windows   :b4, 3, 4
    net9.0-windows   :b5, 4, 5
    net10.0-windows  :b6, 5, 6

    section Wpf.Ui.DependencyInjection
    netstandard2.0   :c1, 0, 1
    netstandard2.1   :c2, 1, 2
    net462           :c3, 2, 3
    net8.0           :c4, 3, 4
    net9.0           :c5, 4, 5
    net10.0          :c6, 5, 6

    section Wpf.Ui.Tray
    net462           :d1, 0, 1
    net472           :d2, 1, 2
    net481           :d3, 2, 3
    net8.0-windows   :d4, 3, 4
    net9.0-windows   :d5, 4, 5
    net10.0-windows  :d6, 5, 6

    section Wpf.Ui.Gallery
    net10.0-windows10.0.26100.0 :e1, 5, 6
ModuleTarget FrameworksWindows TFMRationale
Wpf.Ui.Abstractionsnetstandard2.0, netstandard2.1, net462, net8.0, net9.0, net10.0NoMaximum compatibility; no WPF or Windows dependency. Consumable by any .NET project.
Wpf.Uinet10.0-windows, net9.0-windows, net8.0-windows, net481, net472, net462YesRequires WPF (<UseWPF>true</UseWPF>) and Win32 P/Invoke. Supports .NET Framework 4.6.2+ for legacy app modernization.
Wpf.Ui.DependencyInjectionnetstandard2.0, netstandard2.1, net462, net8.0, net9.0, net10.0NoOnly depends on abstractions and MS DI interfaces. No WPF dependency.
Wpf.Ui.Traynet10.0-windows, net9.0-windows, net8.0-windows, net481, net472, net462YesRequires WPF + Win32 Shell32 interop for tray icons.
Wpf.Ui.SyntaxHighlightnet10.0-windows, net9.0-windows, net8.0-windows, net481, net472, net462YesRequires WPF for custom control rendering.
Wpf.Ui.ToastNotificationsnet10.0-windows, net9.0-windows, net8.0-windows, net481, net472, net462YesSame targeting as core library (currently stub).
Wpf.Ui.FlaUInet10.0-windows, net9.0-windows, net8.0-windows, net481YesTest automation; constrained by FlaUI.Core compatibility.
Wpf.Ui.FontMappernet10.0NoConsole build tool; targets latest runtime only.
Wpf.Ui.Gallerynet10.0-windows10.0.26100.0YesDemo app targets latest .NET + latest Windows SDK for full feature demonstration.
Wpf.Ui.Extensionnet481 (via VSIX SDK)N/AVS 2022 VSIX extension; targets .NET Framework 4.8.1 per VSIX SDK requirements.

6. Service Registration & DI Integration

The following sequence diagram shows how WPF UI integrates with Microsoft.Extensions.DependencyInjection via the Generic Host pattern used in the Gallery and sample applications.

mermaid
sequenceDiagram
    participant App as Application Startup
    participant Host as IHostBuilder
    participant SC as IServiceCollection
    participant Ext as ServiceCollectionExtensions
    participant SP as IServiceProvider
    participant CS as ControlsServices
    participant NavView as NavigationView
    participant Provider as INavigationViewPageProvider

    App->>Host: Host.CreateDefaultBuilder()
    App->>Host: ConfigureServices(services => ...)

    Host->>SC: services.AddSingleton<INavigationService, NavigationService>()
    Host->>SC: services.AddSingleton<IContentDialogService, ContentDialogService>()
    Host->>SC: services.AddSingleton<ISnackbarService, SnackbarService>()
    Host->>Ext: services.AddNavigationViewPageProvider<DI_PageProvider>()
    Ext->>SC: Register INavigationViewPageProvider

    Host->>SC: services.AddTransient<DashboardPage>()
    Host->>SC: services.AddTransient<SettingsPage>()

    App->>Host: Build()
    Host->>SP: Create IServiceProvider

    App->>CS: ControlsServices.Initialize(serviceProvider)
    CS->>CS: Store IServiceProvider for control-level resolution

    Note over NavView,Provider: At runtime, when NavigationView needs a page:
    NavView->>Provider: GetPage(typeof(DashboardPage))
    Provider->>SP: GetRequiredService(typeof(DashboardPage))
    SP-->>Provider: DashboardPage instance
    Provider-->>NavView: Resolved page

7. Control Lifecycle

WPF UI controls follow the standard WPF element lifecycle with additional steps for Fluent Design theming and Win32 interop integration.

mermaid
stateDiagram-v2
    [*] --> Constructed: new MyControl()
    Constructed --> Constructed: Static ctor: DefaultStyleKeyProperty.OverrideMetadata()

    Constructed --> Loaded: Added to visual tree
    Loaded --> TemplateApplied: OnApplyTemplate()
    TemplateApplied --> TemplateApplied: GetTemplateChild() binds named parts

    TemplateApplied --> Themed: DynamicResource brushes resolved
    Themed --> Themed: ApplicationThemeManager.Changed → re-resolve brushes

    Themed --> Unloaded: Removed from visual tree
    Unloaded --> Loaded: Re-added to visual tree

    Unloaded --> GarbageCollected: No references remain
    GarbageCollected --> [*]

    note right of Constructed
        DependencyProperties registered
        via static readonly fields
    end note

    note right of TemplateApplied
        Controls bind template parts
        (e.g., PART_CloseButton)
        and hook event handlers
    end note

    note right of Themed
        Theme changes trigger
        DynamicResource updates
        without re-creating controls
    end note

Lifecycle Details

PhaseTriggerWPF UI Actions
Constructednew / XAML parserStatic constructor registers DefaultStyleKey; DependencyProperties are static
LoadedAdded to visual treeControl subscribes to theme events if needed
Template AppliedOnApplyTemplate()Named template parts (PART_*) resolved via GetTemplateChild()
ThemedResource resolutionDynamicResource brushes resolve from current theme dictionary
UnloadedRemoved from treeEvent handlers and hooks should be cleaned up
GCNo remaining referencesStandard .NET garbage collection

Conditional Compilation

The codebase uses #if directives to handle API differences across target frameworks:

DirectiveUsage
NET5_0_OR_GREATEREnvironment.OSVersion.Version vs. registry-based fallback for OS detection
NET6_0_OR_GREATERDisposeAsync for CancellationTokenRegistration
NET48_OR_GREATER or NETCOREAPP3_0_OR_GREATERIServiceProvider support in controls
NET8_0_OR_GREATERNewer framework API usage

PolySharp provides polyfills (e.g., IsExternalInit, CallerArgumentExpression, nullable attributes) so that C# 14 language features can be used across all target frameworks.