docs/architecture/cross-cutting/theming-and-appearance.md
The WPF UI library implements a comprehensive theming system that supports Light, Dark, and four high-contrast themes. The system automatically synchronizes with OS theme changes, manages accent colors, and provides window backdrop effects (Mica, Acrylic, Tabbed).
Location: src/Wpf.Ui/Appearance/ApplicationThemeManager.cs
Static class responsible for applying and managing application themes. Key functionality:
The manager uses URI-based resource dictionary swapping, searching application-level merged dictionaries for URIs containing 'wpf.ui;' and 'theme', then replacing them with the appropriate theme file.
Location: src/Wpf.Ui/Appearance/ApplicationAccentColorManager.cs
Static class for accent color management:
Uses WinRT IUISettings3 COM interface to retrieve system accent colors (Accent, AccentLight1-3, AccentDark1-3) with registry fallback to DWM AccentColor.
Dynamic Resources Updated:
Location: src/Wpf.Ui/Appearance/SystemThemeWatcher.cs
Static class providing automatic OS theme synchronization:
Implementation uses WndProc message interception via HwndSource to listen for:
WM_DWMCOLORIZATIONCOLORCHANGEDWM_THEMECHANGEDWM_SYSCOLORCHANGEWhen detected, triggers ApplicationThemeManager.ApplySystemTheme().
Location: src/Wpf.Ui/Appearance/WindowBackgroundManager.cs
Static class for window appearance management:
Location: src/Wpf.Ui/Appearance/ResourceDictionaryManager.cs
Internal helper class for resource dictionary manipulation:
Six XAML resource dictionaries located in src/Wpf.Ui/Resources/Theme/:
Located in src/Wpf.Ui/Resources/ (parent directory, not the Theme/ subdirectory):
The accent color system provides dynamic, theme-aware colors derived from Windows system settings:
System Accent Color (from WinRT UISettings)
├── Primary Accent (direct system color)
├── Secondary Accent (lighter/darker variant)
└── Tertiary Accent (additional variant)
// Retrieves colors via WinRT IUISettings3 COM interface
var uiSettings = new Windows.UI.ViewManagement.UISettings();
var accent = uiSettings.GetColorValue(UIColorType.Accent);
var accentLight1 = uiSettings.GetColorValue(UIColorType.AccentLight1);
var accentDark1 = uiSettings.GetColorValue(UIColorType.AccentDark1);
Three backdrop effect types available via WindowBackdropType enum:
Windows 11+ translucent backdrop with desktop wallpaper bleed-through. Applied via DwmSetWindowAttribute with DWMWA_SYSTEMBACKDROP_TYPE.
Translucent acrylic material effect with blur. Requires Windows 10 Fall Creators Update or later.
Windows 11 tabbed window effect grouping windows in the taskbar.
Effects are applied through DWM (Desktop Window Manager) APIs in WindowBackgroundManager and consumed by FluentWindow control.
sequenceDiagram
participant User
participant App
participant SystemThemeWatcher
participant WndProc
participant ApplicationThemeManager
participant ResourceDictionaryManager
participant UI
User->>App: Change OS Theme
WndProc->>SystemThemeWatcher: WM_THEMECHANGED
SystemThemeWatcher->>ApplicationThemeManager: ApplySystemTheme()
ApplicationThemeManager->>ApplicationThemeManager: GetSystemTheme()
ApplicationThemeManager->>ResourceDictionaryManager: UpdateDictionary("theme", newUri)
ResourceDictionaryManager->>UI: Swap Theme XAML
ApplicationThemeManager->>ApplicationThemeManager: Fire Changed Event
ApplicationThemeManager->>UI: Trigger Visual Update
UI->>User: Updated Appearance
// Apply dark theme
ApplicationThemeManager.Apply(ApplicationTheme.Dark);
// Get current theme
ApplicationTheme current = ApplicationThemeManager.GetAppTheme();
public MainWindow()
{
InitializeComponent();
// Enable automatic theme synchronization
Appearance.SystemThemeWatcher.Watch(this);
}
// Apply custom accent color
Color myAccent = Color.FromRgb(0, 120, 215);
ApplicationAccentColorManager.Apply(
myAccent,
ApplicationTheme.Dark,
systemGlassColor: false,
systemAccentColor: true
);
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Select theme via ThemesDictionary -->
<ui:ThemesDictionary Theme="Dark" />
<ui:ControlsDictionary />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The theme managers use static class design for simple, globally-accessible APIs. This pattern trades testability for API simplicity and ensures single-instance theme state across the application.
Theme changes occur via runtime resource dictionary replacement rather than restart-required configuration. This enables live theme switching without application restart.
Deep integration with Windows theme system via WndProc message hooks and WinRT UISettings ensures automatic synchronization with user preferences.
Theme system gracefully degrades on older Windows versions, falling back to registry-based accent color detection when WinRT APIs are unavailable.