Help us improve
Share bugs, ideas, or general feedback.
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.
npx claudepluginhub microsoft/win-dev-skills --plugin winuiHow 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...
Reviews WinUI 3 code for MVVM compliance, x:Bind correctness, accessibility, theming, security, and performance before committing.
Guides implementation of Microsoft's Fluent 2 design system: light/depth/motion/material/scale elements, Acrylic/Mica, reveal highlights, animations, responsive containers, token theming for Windows apps, React UIs, Microsoft 365.
Building accessible .NET UI. SemanticProperties, ARIA, AutomationPeer, testing tools per platform.
Share bugs, ideas, or general feedback.
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 |