From winui
Designs WinUI 3 UIs and reviews XAML for correctness, covering layout planning, control selection, Fluent Design, theming (Light/Dark/HighContrast), typography, spacing, brushes, accessibility, and data binding.
How this skill is triggered — by the user, by Claude, or both
Slash command
/winui:winui-designThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Before picking controls, search the catalogue.** This skill ships `winui-search.exe` alongside this `SKILL.md`. It indexes 100+ WinUI Gallery controls, every Windows Community Toolkit scenario, and a curated set of platform integration patterns (JumpList, Share, file pickers, drag-drop). Use it to ground every control choice in a real shipping sample **before writing any XAML** — this is th...
Before picking controls, search the catalogue. This skill ships
winui-search.exealongside thisSKILL.md. It indexes 100+ WinUI Gallery controls, every Windows Community Toolkit scenario, and a curated set of platform integration patterns (JumpList, Share, file pickers, drag-drop). Use it to ground every control choice in a real shipping sample before writing any XAML — this is the difference between guessing property names and copying canonical code..\winui-search.exe search "<feature description>" # shortlist of matching scenarios .\winui-search.exe get <id> # full XAML + C# + pitfall notes .\winui-search.exe list # browse everything .\winui-search.exe update # refresh embedded snapshots from GitHubWorkflow: batch every search you need for the current page or feature → pick the best ID from each shortlist →
getthe full code for each → then write XAML using those samples as reference. Do NOT interleave searching with coding. Search one feature per query — the BM25 scoring rewards focused queries.
| App Type | Anchor Control | Reference App |
|---|---|---|
| Settings / config tool | NavigationView Left + SettingsCard | Windows Settings |
| Document / session editor | TabView + full-width content | Windows Terminal, Notepad |
| Hierarchical browser | TreeView + ListView + BreadcrumbBar | File Explorer |
| Developer tool / dashboard | NavigationView + card layout | Dev Home |
| Single-purpose utility | Mode switcher + compact grid | Calculator |
Navigation: 2-7 sections → NavigationView; document tabs → TabView; breadcrumb trail → BreadcrumbBar; 2-3 modes → SelectorBar.
Data display: Vertical list → ListView; tiles/grid → GridView or ItemsRepeater + UniformGridLayout; hierarchy → TreeView; tabular → ListView with Grid column headers; master-detail → ListView + detail Grid.
Input: Text → TextBox; number → NumberBox; search → AutoSuggestBox; date → CalendarDatePicker; boolean → ToggleSwitch; pick one from 2-3 → RadioButtons; pick one from 4+ → ComboBox.
Feedback: Blocking decision → ContentDialog; contextual action → Flyout/MenuFlyout; onboarding → TeachingTip; inline status → InfoBar; system notification → AppNotification.
Grid for structure, StackPanel only for simple stacking of few itemsWidth="*" with 24px paddingGrid row at bottom; toolbar: CommandBar or title bar buttons| ❌ Don't | ✅ Do Instead |
|---|---|
| Centered floating card on background | Content fills window with padding |
| Custom pill/segment tab switcher | NavigationView Top or SelectorBar |
| Equal-width 50/50 column split | Fixed sidebar (300-360px) + flexible main |
Hardcoded colors (#FF0000) | {ThemeResource} brushes |
ScrollViewer around ListView | ListView has built-in scrolling |
| Custom ControlTemplate for standard controls | Built-in controls with style overrides |
{ThemeResource BrushName} at usage sites — updates on theme change{StaticResource} with ResourceKey redirects inside theme dictionaries — zero allocationResourceKey must end in Brush (target the SolidColorBrush, not the Color)x:Key="Light", x:Key="Dark", x:Key="HighContrast" — never use x:Key="Default"{ThemeResource} updates; {StaticResource} does not<!-- Correct: StaticResource redirect in theme dictionary -->
<StaticResource x:Key="MyBrush" ResourceKey="ControlFillColorDefaultBrush" />
<!-- Wrong: inline SolidColorBrush allocates new object -->
<SolidColorBrush x:Key="MyBrush" Color="{StaticResource ControlFillColorDefault}" />
Only 8 system color brushes allowed in HC dictionaries:
| Background | Foreground | Use Case |
|---|---|---|
SystemColorWindowColorBrush | SystemColorWindowTextColorBrush | General content |
SystemColorHighlightColorBrush | SystemColorHighlightTextColorBrush | Selected/hover |
SystemColorButtonFaceColorBrush | SystemColorButtonTextColorBrush | Buttons |
SystemColorWindowColorBrush | SystemColorHotlightColorBrush | Hyperlinks |
SystemColorWindowColorBrush | SystemColorGrayTextColorBrush | Disabled content |
HC prohibitions: No hardcoded colors, no opacity, no accent colors, no regular WinUI brushes, no SystemColor* in Light/Dark dicts. Use empty HC dict when WinUI defaults suffice. Set HighContrastAdjustment = None at app level.
| Style | Size | Weight | Use For |
|---|---|---|---|
CaptionTextBlockStyle | 12px | Regular | Small labels, timestamps |
BodyTextBlockStyle | 14px | Regular | Body text (default — don't set explicitly) |
BodyStrongTextBlockStyle | 14px | Semibold | Emphasized body text |
SubtitleTextBlockStyle | 20px | Semibold | Section headers, card titles |
TitleTextBlockStyle | 28px | Semibold | Page titles |
TitleLargeTextBlockStyle | 40px | Semibold | Large feature titles |
DisplayTextBlockStyle | 68px | Semibold | Hero text |
Use SemiBold, never Bold. Minimum 12px. BasedOn styles must not re-declare inherited properties.
ControlCornerRadius (4px) for controls, OverlayCornerRadius (8px) for overlays — never hardcodeRowSpacing/ColumnSpacing instead of spacer elementsMinHeight/MinWidth instead of fixed sizingDon't set WinUI default values — blocks future updates:
BodyTextBlockStyle on TextBlock, TextFillColorPrimaryBrush foreground, TextWrapping="NoWrap", Padding="0", Margin="0"| Surface | Background | Border |
|---|---|---|
| Flyouts, tooltips | AcrylicBackgroundFillColorDefaultBrush | SurfaceStrokeColorFlyoutBrush |
| UI surfaces | AcrylicBackgroundFillColorBaseBrush | SurfaceStrokeColorDefaultBrush |
Use BackgroundSizing="InnerBorderEdge" on bordered acrylic. ThemeShadow requires Translation="0,0,32" and 12px parent padding.
{x:Bind} over {Binding}, explicit Mode=OneWay/TwoWay, x:DataType on DataTemplatex:Bind TwoWay — always add UpdateSourceTrigger=PropertyChanged so the ViewModel updates on each keystroke instead of waiting for LostFocus. Without it, UIA automation (set-value) and programmatic changes won't commit to the ViewModel.
<TextBox Text="{x:Bind ViewModel.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
VisualStateManager for visual property changes, not code-behindIValueConverter — prefer x:Bind with functionsBool negation and Visibility functions — define static methods in code-behind:
// In code-behind (e.g., MainPage.xaml.cs)
public static Visibility BoolToVisibility(bool value) =>
value ? Visibility.Visible : Visibility.Collapsed;
public static Visibility InvertBoolToVisibility(bool value) =>
value ? Visibility.Collapsed : Visibility.Visible;
public static bool IsNotBusy(bool isLoading) => !isLoading;
<!-- Usage in XAML -->
Visibility="{x:Bind local:MainPage.BoolToVisibility(ViewModel.IsLoading), Mode=OneWay}"
IsEnabled="{x:Bind local:MainPage.IsNotBusy(ViewModel.IsLoading), Mode=OneWay}"
❌ NEVER use Converter={x:Null} — it crashes at runtime.
AutomationProperties.Name on icon-only controlsAutomationProperties.AutomationId on all interactive controlsButton, HyperlinkButton) — not clickable Border/TextBlockDividerStrokeColorDefaultBrush for dividersSetting attached properties in code-behind — WinUI attached properties use static methods, NOT object initializer syntax:
using Microsoft.UI.Xaml.Automation; // required for AutomationProperties
// ❌ WRONG — object initializer doesn't work for attached properties
var btn = new Button { AutomationProperties = { AutomationId = "BtnSave" } };
// ✅ CORRECT — static setter method
var btn = new Button { Content = "Save" };
AutomationProperties.SetAutomationId(btn, "BtnSave");
AutomationProperties.SetName(btn, "Save button");
Grid.SetRow(btn, 1);
Grid.SetColumn(btn, 0);
ToolTipService.SetToolTip(btn, "Save the current document");
{StaticResource} not {ThemeResource}px suffix on numeric values, no commented-out XAML| File | Read when... |
|---|---|
references/approved-brushes.md | Looking up correct WinUI brush names and usage rules |
references/theme-aware-resources.md | Implementing ThemeResource/StaticResource, High Contrast, acrylic pairings |
references/code-review-checklist.md | Reviewing XAML changes for correctness |
references/pr-review-patterns.md | Applying concrete review fixes and patterns |
references/control-styles.md | Customizing built-in control styles |
references/typography-and-spacing.md | Detailed type ramp, spacing grid, and sizing examples |
references/colors-and-materials.md | Theme brush catalog, Mica/Acrylic surface pairings, material usage |
references/iconography-and-motion.md | Icon guidelines, animation patterns, connected animations |
npx claudepluginhub microsoft/win-dev-skills --plugin winuiReviews WinUI 3 code for MVVM compliance, x:Bind correctness, accessibility, theming, security, and performance before committing.
Provides guidance on Microsoft's Fluent 2 design system: five foundational elements (light, depth, motion, material, scale), Acrylic/Mica materials, reveal highlight, connected animations, responsive containers, and token theming architecture.
Building accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing tools per platform.