# 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["Wpf.Ui.Abstractions
NuGet: WPF-UI.Abstractions
Zero-dependency interfaces:
INavigationViewPageProvider,
INavigationAware, INavigableView<T>
Targets: netstandard2.0/2.1,
net462, net8.0, net9.0, net10.0
"] Core["Wpf.Ui
NuGet: WPF-UI
77+ controls, theming, services,
Win32 interop
Targets: net10.0-windows,
net9.0/8.0-windows,
net481, net472, net462
"] DI["Wpf.Ui.DependencyInjection
NuGet: WPF-UI.DependencyInjection
MS DI integration
Targets: netstandard2.0/2.1,
net462, net8.0, net9.0, net10.0
"] Tray["Wpf.Ui.Tray
NuGet: WPF-UI.Tray
System tray icons via Shell32
Targets: net10.0/9.0/8.0-windows,
net481, net472, net462
"] Syntax["Wpf.Ui.SyntaxHighlight
NuGet: WPF-UI.SyntaxHighlight
Code syntax highlighting (WIP)
Targets: net10.0/9.0/8.0-windows,
net481, net472, net462
"] Toast["Wpf.Ui.ToastNotifications
NuGet: WPF-UI.ToastNotifications
Toast notifications (STUB,
all throw NotImplementedException)
Targets: net10.0/9.0/8.0-windows,
net481, net472, net462
"] Gallery["Wpf.Ui.Gallery
Demo/showcase app
MVVM with CommunityToolkit.Mvvm
Target: net10.0-windows10.0.26100.0"] FlaUI["Wpf.Ui.FlaUI
NuGet: WPF-UI.FlaUI
Test automation helpers
Targets: net10.0/9.0/8.0-windows,
net481
"] FontMapper["Wpf.Ui.FontMapper
Build tool: icon enum generation
from FluentSystemIcons JSON
Target: net10.0"] Extension["Wpf.Ui.Extension
VS 2022 VSIX extension
Project templates (Blank, Compact, Fluent)
Target: net481 (VSIX SDK)"] %% 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:** | Package | Direct dependencies | |---------|-------------------| | `Wpf.Ui.Abstractions` | None (zero external dependencies) | | `Wpf.Ui` | `Wpf.Ui.Abstractions`, Microsoft.Windows.CsWin32 (build-time), System.Memory | | `Wpf.Ui.DependencyInjection` | `Wpf.Ui.Abstractions`, Microsoft.Extensions.DependencyInjection.Abstractions 3.1.0 | | `Wpf.Ui.Tray` | `Wpf.Ui`, System.Drawing.Common | | `Wpf.Ui.SyntaxHighlight` | `Wpf.Ui` | | `Wpf.Ui.ToastNotifications` | None (standalone stub) | | `Wpf.Ui.Gallery` | `Wpf.Ui`, `Wpf.Ui.DependencyInjection`, `Wpf.Ui.Tray`, `Wpf.Ui.SyntaxHighlight`, `Wpf.Ui.ToastNotifications`, CommunityToolkit.Mvvm, Microsoft.Extensions.Hosting | | `Wpf.Ui.FlaUI` | FlaUI.Core | | `Wpf.Ui.FontMapper` | None | | `Wpf.Ui.Extension` | VSIX 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<T>"] 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: | File | Responsibility | |------|---------------| | `NavigationView.Base.cs` | Core logic, constructor, static constructor | | `NavigationView.Properties.cs` | DependencyProperty registrations | | `NavigationView.Events.cs` | RoutedEvent registrations | | `NavigationView.Navigation.cs` | Page navigation logic | | `NavigationView.TemplateParts.cs` | Template part bindings (OnApplyTemplate) | | `NavigationView.AttachedProperties.cs` | Attached property definitions | Key controls: `FluentWindow`, `NavigationView`, `TitleBar`, `ContentDialog`, `NumberBox`, `AutoSuggestBox`, `ToggleSwitch`, `Snackbar`, `BreadcrumbBar`, `InfoBar`, `RatingControl`, `ProgressRing`. #### Layer 2 -- Appearance/Theming | Class | Pattern | Responsibility | |-------|---------|---------------| | `ApplicationThemeManager` | Static | Runtime theme switching via ResourceDictionary swap. Fires `ThemeChangedEvent`. | | `ApplicationAccentColorManager` | Static | Updates 20+ dynamic color resources (SystemAccentColor, AccentFillColorDefault, etc.) from WinRT UISettings or registry fallback. | | `SystemThemeWatcher` | Static | Hooks WndProc for `WM_THEMECHANGED`, `WM_DWMCOLORIZATIONCOLORCHANGED`, `WM_SYSCOLORCHANGE`. Auto-syncs app theme with OS. | | `WindowBackgroundManager` | Static | Applies DWM backdrop effects (Mica, Acrylic, Tabbed) via `DwmSetWindowAttribute`. | | `ResourceDictionaryManager` | Internal | URI-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. | Service | Interface | Wraps | |---------|-----------|-------| | `NavigationService` | `INavigationService` | `INavigationView` control | | `ContentDialogService` | `IContentDialogService` | `ContentDialog` control | | `SnackbarService` | `ISnackbarService` | `Snackbar` control | | `ThemeService` | `IThemeService` | `ApplicationThemeManager` static class | | `TaskBarService` | `ITaskBarService` | COM `ITaskbarList4` via Win32 interop | #### Layer 4 -- Infrastructure | Component | Contents | |-----------|----------| | **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`, `RelayCommand` -- 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 | Path | Contents | |------|----------| | `Resources/Theme/` | 6 XAML theme dictionaries (Light, Dark, HC1, HC2, HCBlack, HCWhite) | | `Resources/Fonts/` | `FluentSystemIcons-Filled.ttf`, `FluentSystemIcons-Regular.ttf` (embedded resources) | | `Resources/Accent.xaml` | Dynamic accent color resources | | `Resources/Palette.xaml` | Fluent Design color palette | | `Resources/StaticColors.xaml` | Non-theme-dependent color constants | | `Resources/Typography.xaml` | Font family, size, and weight resources | | `Resources/Variables.xaml` | Corner radius, spacing, sizing tokens | | `Resources/Wpf.Ui.xaml` | Master ResourceDictionary that merges all 77+ control style dictionaries | | `Resources/DefaultContextMenu.xaml` | Styled context menu for TextBox-like controls | | `Resources/DefaultFocusVisualStyle.xaml` | Fluent 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 { <> +ControlAppearance Appearance } class IIconControl { <> +IconElement? Icon } class IThemeControl { <> +ApplicationTheme ApplicationTheme } class IDpiAwareControl { <> +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 { <> .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 ``` **3. Registration in master dictionary** (`Resources/Wpf.Ui.xaml`): ```xml ``` ### 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. ### CommunityToolkit.Mvvm in Gallery and Samples 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` 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();` 3. The `ControlsServices.Initialize(IServiceProvider)` static method enables control-level service resolution. ### Async Dialog Pattern `ContentDialog.ShowAsync()` returns `Task` 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 ``` | Module | Target Frameworks | Windows TFM | Rationale | |--------|------------------|-------------|-----------| | **Wpf.Ui.Abstractions** | `netstandard2.0`, `netstandard2.1`, `net462`, `net8.0`, `net9.0`, `net10.0` | No | Maximum compatibility; no WPF or Windows dependency. Consumable by any .NET project. | | **Wpf.Ui** | `net10.0-windows`, `net9.0-windows`, `net8.0-windows`, `net481`, `net472`, `net462` | Yes | Requires WPF (`true`) and Win32 P/Invoke. Supports .NET Framework 4.6.2+ for legacy app modernization. | | **Wpf.Ui.DependencyInjection** | `netstandard2.0`, `netstandard2.1`, `net462`, `net8.0`, `net9.0`, `net10.0` | No | Only depends on abstractions and MS DI interfaces. No WPF dependency. | | **Wpf.Ui.Tray** | `net10.0-windows`, `net9.0-windows`, `net8.0-windows`, `net481`, `net472`, `net462` | Yes | Requires WPF + Win32 Shell32 interop for tray icons. | | **Wpf.Ui.SyntaxHighlight** | `net10.0-windows`, `net9.0-windows`, `net8.0-windows`, `net481`, `net472`, `net462` | Yes | Requires WPF for custom control rendering. | | **Wpf.Ui.ToastNotifications** | `net10.0-windows`, `net9.0-windows`, `net8.0-windows`, `net481`, `net472`, `net462` | Yes | Same targeting as core library (currently stub). | | **Wpf.Ui.FlaUI** | `net10.0-windows`, `net9.0-windows`, `net8.0-windows`, `net481` | Yes | Test automation; constrained by FlaUI.Core compatibility. | | **Wpf.Ui.FontMapper** | `net10.0` | No | Console build tool; targets latest runtime only. | | **Wpf.Ui.Gallery** | `net10.0-windows10.0.26100.0` | Yes | Demo app targets latest .NET + latest Windows SDK for full feature demonstration. | | **Wpf.Ui.Extension** | `net481` (via VSIX SDK) | N/A | VS 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() Host->>SC: services.AddSingleton() Host->>SC: services.AddSingleton() Host->>Ext: services.AddNavigationViewPageProvider() Ext->>SC: Register INavigationViewPageProvider Host->>SC: services.AddTransient() Host->>SC: services.AddTransient() 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 | Phase | Trigger | WPF UI Actions | |-------|---------|----------------| | **Constructed** | `new` / XAML parser | Static constructor registers `DefaultStyleKey`; DependencyProperties are static | | **Loaded** | Added to visual tree | Control subscribes to theme events if needed | | **Template Applied** | `OnApplyTemplate()` | Named template parts (`PART_*`) resolved via `GetTemplateChild()` | | **Themed** | Resource resolution | `DynamicResource` brushes resolve from current theme dictionary | | **Unloaded** | Removed from tree | Event handlers and hooks should be cleaned up | | **GC** | No remaining references | Standard .NET garbage collection | --- ### Conditional Compilation The codebase uses `#if` directives to handle API differences across target frameworks: | Directive | Usage | |-----------|-------| | `NET5_0_OR_GREATER` | `Environment.OSVersion.Version` vs. registry-based fallback for OS detection | | `NET6_0_OR_GREATER` | `DisposeAsync` for `CancellationTokenRegistration` | | `NET48_OR_GREATER` or `NETCOREAPP3_0_OR_GREATER` | `IServiceProvider` support in controls | | `NET8_0_OR_GREATER` | Newer 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.