From wpf-dev-pack
Manages WPF Style definitions and ResourceDictionary patterns including BasedOn inheritance and resource merging. Use when building theme systems, organizing resources, or choosing between StaticResource and DynamicResource.
npx claudepluginhub christian289/dotnet-with-claudecode --plugin wpf-dev-packThis skill uses the workspace's default tool permissions.
Effectively managing Style and ResourceDictionary for consistent UI and maintainability.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
Effectively managing Style and ResourceDictionary for consistent UI and maintainability.
<Window.Resources>
<!-- Explicit style: must reference by key to apply -->
<Style x:Key="PrimaryButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="#2196F3"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="16,8"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
</Window.Resources>
<Button Style="{StaticResource PrimaryButtonStyle}" Content="Primary"/>
<Window.Resources>
<!-- Implicit style: auto-applied to all controls of that type -->
<Style TargetType="{x:Type Button}">
<Setter Property="Margin" Value="5"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
</Window.Resources>
<!-- Style automatically applied -->
<Button Content="Auto Styled"/>
<!-- Base button style -->
<Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Padding" Value="12,6"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Cursor" Value="Hand"/>
</Style>
<!-- Primary button: inherits base style -->
<Style x:Key="PrimaryButtonStyle" TargetType="{x:Type Button}"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="#2196F3"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<!-- Secondary button: inherits base style -->
<Style x:Key="SecondaryButtonStyle" TargetType="{x:Type Button}"
BasedOn="{StaticResource BaseButtonStyle}">
<Setter Property="Background" Value="#E0E0E0"/>
<Setter Property="Foreground" Value="#424242"/>
</Style>
<!-- Explicit style inheriting from implicit style -->
<Style TargetType="{x:Type Button}">
<Setter Property="Margin" Value="5"/>
</Style>
<Style x:Key="SpecialButtonStyle" TargetType="{x:Type Button}"
BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Background" Value="Gold"/>
</Style>
๐ Themes/
โโโ ๐ Colors.xaml (Color definitions)
โโโ ๐ Brushes.xaml (Brush definitions)
โโโ ๐ Converters.xaml (Converter definitions)
โโโ ๐ Controls/
โ โโโ ๐ Button.xaml (Button styles)
โ โโโ ๐ TextBox.xaml (TextBox styles)
โ โโโ ๐ ListBox.xaml (ListBox styles)
โโโ ๐ Generic.xaml (Merged dictionary)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Base color palette -->
<Color x:Key="PrimaryColor">#2196F3</Color>
<Color x:Key="PrimaryDarkColor">#1976D2</Color>
<Color x:Key="PrimaryLightColor">#BBDEFB</Color>
<Color x:Key="AccentColor">#FF4081</Color>
<Color x:Key="TextPrimaryColor">#212121</Color>
<Color x:Key="TextSecondaryColor">#757575</Color>
<Color x:Key="BackgroundColor">#FAFAFA</Color>
<Color x:Key="SurfaceColor">#FFFFFF</Color>
<Color x:Key="ErrorColor">#F44336</Color>
<Color x:Key="SuccessColor">#4CAF50</Color>
<Color x:Key="WarningColor">#FFC107</Color>
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Merge Colors.xaml -->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Colors.xaml"/>
</ResourceDictionary.MergedDictionaries>
<!-- SolidColorBrush definitions -->
<SolidColorBrush x:Key="PrimaryBrush" Color="{StaticResource PrimaryColor}"/>
<SolidColorBrush x:Key="PrimaryDarkBrush" Color="{StaticResource PrimaryDarkColor}"/>
<SolidColorBrush x:Key="PrimaryLightBrush" Color="{StaticResource PrimaryLightColor}"/>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource AccentColor}"/>
<SolidColorBrush x:Key="TextPrimaryBrush" Color="{StaticResource TextPrimaryColor}"/>
<SolidColorBrush x:Key="TextSecondaryBrush" Color="{StaticResource TextSecondaryColor}"/>
<SolidColorBrush x:Key="BackgroundBrush" Color="{StaticResource BackgroundColor}"/>
<SolidColorBrush x:Key="SurfaceBrush" Color="{StaticResource SurfaceColor}"/>
</ResourceDictionary>
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<!-- Order matters: merge in dependency order -->
<ResourceDictionary Source="Colors.xaml"/>
<ResourceDictionary Source="Brushes.xaml"/>
<ResourceDictionary Source="Converters.xaml"/>
<ResourceDictionary Source="Controls/Button.xaml"/>
<ResourceDictionary Source="Controls/TextBox.xaml"/>
<ResourceDictionary Source="Controls/ListBox.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
| Aspect | StaticResource | DynamicResource |
|---|---|---|
| Evaluation time | Once at XAML load | Every time at runtime |
| Performance | Fast | Relatively slower |
| Change reflection | No | Auto-reflected |
| Forward reference | Not available | Available |
| Use case | Fixed resources | Theme changes, dynamic resources |
<!-- StaticResource: immutable resources -->
<Button Background="{StaticResource PrimaryBrush}"/>
<!-- DynamicResource: when runtime changes needed -->
<Border Background="{DynamicResource ThemeBackgroundBrush}"/>
namespace MyApp.Services;
using System;
using System.Windows;
public sealed class ThemeService
{
private const string LightThemePath = "/Themes/LightTheme.xaml";
private const string DarkThemePath = "/Themes/DarkTheme.xaml";
/// <summary>
/// Switch theme
/// </summary>
public void SwitchTheme(bool isDark)
{
var themePath = isDark ? DarkThemePath : LightThemePath;
var themeUri = new Uri(themePath, UriKind.Relative);
var app = Application.Current;
var mergedDicts = app.Resources.MergedDictionaries;
// Remove existing theme
for (var i = mergedDicts.Count - 1; i >= 0; i--)
{
var dict = mergedDicts[i];
if (dict.Source?.OriginalString.Contains("Theme") == true)
{
mergedDicts.RemoveAt(i);
}
}
// Add new theme
mergedDicts.Add(new ResourceDictionary { Source = themeUri });
}
}
namespace MyApp.Helpers;
using System.Windows;
using System.Windows.Media;
public static class ResourceHelper
{
/// <summary>
/// Find resource (FindResource - throws if not found)
/// </summary>
public static Brush GetBrush(string key)
{
return (Brush)Application.Current.FindResource(key);
}
/// <summary>
/// Find resource (TryFindResource - returns null if not found)
/// </summary>
public static Brush? TryGetBrush(string key)
{
return Application.Current.TryFindResource(key) as Brush;
}
/// <summary>
/// Find resource from element (searches upward)
/// </summary>
public static T? FindResource<T>(FrameworkElement element, string key) where T : class
{
return element.TryFindResource(key) as T;
}
}
// Set DynamicResource from code
button.SetResourceReference(Button.BackgroundProperty, "PrimaryBrush");
// Set StaticResource from code (direct resource assignment)
button.Background = (Brush)FindResource("PrimaryBrush");
namespace MyLib.Controls;
using System.Windows;
public static class MyLibResources
{
// Define component resource key
public static readonly ComponentResourceKey PrimaryBrushKey =
new(typeof(MyLibResources), "PrimaryBrush");
public static readonly ComponentResourceKey ButtonStyleKey =
new(typeof(MyLibResources), "ButtonStyle");
}
<!-- Generic.xaml (in Themes folder) -->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyLib.Controls">
<SolidColorBrush x:Key="{ComponentResourceKey TypeInTargetAssembly={x:Type local:MyLibResources}, ResourceId=PrimaryBrush}"
Color="#2196F3"/>
</ResourceDictionary>
<!-- Consumer side -->
<Button Background="{StaticResource {x:Static local:MyLibResources.PrimaryBrushKey}}"/>
1. Element's own Resources
2. Parent element Resources (searching upward in Visual Tree)
3. Window/Page Resources
4. Application.Resources
5. Theme resources (Generic.xaml)
6. System resources (SystemColors, SystemFonts)