Files
awesome-copilot/instructions/winui3.instructions.md
Niels Laute dcc2ee1086 Add WinUI 3 Expert (#865)
* WinUI agent

* Improvements

* Fixes

* Add WinUI 3 unit testing guidance across agent, instructions, and skill

- Expanded Testing section in agent with Unit Test App project setup,
  [TestMethod] vs [UITestMethod] attributes, and code examples
- Added Testing rules to instructions file
- Added Testing Migration section to migration guide skill with
  UWP-to-WinUI 3 test project mapping and updated checklist

Reference: https://learn.microsoft.com/en-us/windows/apps/winui/winui3/testing/create-winui-unit-test-project

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Update agents/winui3-expert.agent.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Copilot tweaks

* Update agents/winui3-expert.agent.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Update agents/winui3-expert.agent.md

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-04 10:04:56 +11:00

10 KiB
Raw Permalink Blame History

description, applyTo
description applyTo
WinUI 3 and Windows App SDK coding guidelines. Prevents common UWP API misuse, enforces correct XAML namespaces, threading, windowing, and MVVM patterns for desktop Windows apps. **/*.xaml, **/*.cs, **/*.csproj

WinUI 3 / Windows App SDK

Critical Rules — NEVER Use Legacy UWP APIs

These UWP patterns are wrong for WinUI 3 desktop apps. Always use the Windows App SDK equivalent.

  • NEVER use Windows.UI.Popups.MessageDialog. Use ContentDialog with XamlRoot set.
  • NEVER show a ContentDialog without setting dialog.XamlRoot = this.Content.XamlRoot first.
  • NEVER use CoreDispatcher.RunAsync or Dispatcher.RunAsync. Use DispatcherQueue.TryEnqueue.
  • NEVER use Window.Current. Track the main window via a static App.MainWindow property.
  • NEVER use Windows.UI.Xaml.* namespaces. Use Microsoft.UI.Xaml.*.
  • NEVER use Windows.UI.Composition. Use Microsoft.UI.Composition.
  • NEVER use Windows.UI.Colors. Use Microsoft.UI.Colors.
  • NEVER use ApplicationView or CoreWindow for window management. Use Microsoft.UI.Windowing.AppWindow.
  • NEVER use CoreApplicationViewTitleBar. Use AppWindowTitleBar.
  • NEVER use GetForCurrentView() patterns (e.g., UIViewSettings.GetForCurrentView()). These do not exist in desktop WinUI 3. Use AppWindow APIs instead.
  • NEVER use UWP PrintManager directly. Use IPrintManagerInterop with a window handle.
  • NEVER use DataTransferManager directly for sharing. Use IDataTransferManagerInterop with a window handle.
  • NEVER use UWP IBackgroundTask. Use Microsoft.Windows.AppLifecycle activation.
  • NEVER use WebAuthenticationBroker. Use OAuth2Manager (Windows App SDK 1.7+).

XAML Patterns

  • The default XAML namespace maps to Microsoft.UI.Xaml, not Windows.UI.Xaml.
  • Prefer {x:Bind} over {Binding} for compiled, type-safe, higher-performance bindings.
  • Set x:DataType on DataTemplate elements when using {x:Bind} — this is required for compiled bindings in templates. On Page/UserControl, x:DataType enables compile-time binding validation but is not strictly required if the DataContext does not change.
  • Use Mode=OneWay for dynamic values, Mode=OneTime for static, Mode=TwoWay only for editable inputs.
  • Do not bind static constants — set them directly in XAML.

Threading

  • Use DispatcherQueue.TryEnqueue(() => { ... }) to update UI from background threads.
  • TryEnqueue returns bool, not a Task — it is fire-and-forget.
  • Check thread access with DispatcherQueue.HasThreadAccess before dispatching.
  • WinUI 3 uses standard STA (not ASTA). No built-in reentrancy protection — be cautious with async code that pumps messages.

Windowing

  • Get the AppWindow from a WinUI 3 Window via WindowNative.GetWindowHandleWin32Interop.GetWindowIdFromWindowAppWindow.GetFromWindowId.
  • Use AppWindow for resize, move, title, and presenter operations.
  • Custom title bar: use AppWindow.TitleBar properties, not CoreApplicationViewTitleBar.
  • Track the main window as App.MainWindow (a static property set in OnLaunched).

Dialogs and Pickers

  • ContentDialog: Always set dialog.XamlRoot = this.Content.XamlRoot before calling ShowAsync().
  • File/Folder Pickers: Initialize with WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd) where hwnd comes from WindowNative.GetWindowHandle(App.MainWindow).
  • Share/Print: Use COM interop interfaces (IDataTransferManagerInterop, IPrintManagerInterop) with window handles.

MVVM and Data Binding

  • Prefer CommunityToolkit.Mvvm ([ObservableProperty], [RelayCommand]) for MVVM infrastructure.
  • Use Microsoft.Extensions.DependencyInjection for service registration and injection.
  • Keep UI (Views) focused on layout and bindings; keep logic in ViewModels and services.
  • Use async/await for I/O and long-running work to keep the UI responsive.

Project Setup

  • Target net10.0-windows10.0.22621.0 (or appropriate TFM for the project's target SDK).
  • Set <UseWinUI>true</UseWinUI> in the project file.
  • Reference the latest stable Microsoft.WindowsAppSDK NuGet package.
  • Use System.Text.Json with source generators for JSON serialization.

C# Code Style

  • Use file-scoped namespaces.
  • Enable nullable reference types. Use is null / is not null instead of == null.
  • Prefer pattern matching over as/is with null checks.
  • PascalCase for types, methods, properties. camelCase for private fields.
  • Allman brace style (opening brace on its own line).
  • Prefer explicit types for built-in types; use var only when the type is obvious.

Accessibility

  • Set AutomationProperties.Name on all interactive controls.
  • Use AutomationProperties.HeadingLevel on section headers.
  • Hide decorative elements with AutomationProperties.AccessibilityView="Raw".
  • Ensure full keyboard navigation (Tab, Enter, Space, arrow keys).
  • Meet WCAG color contrast requirements.

Performance

  • Prefer {x:Bind} (compiled) over {Binding} (reflection-based).
  • NativeAOT: Under Native AOT compilation, {Binding} (reflection-based) does not work at all. Only {x:Bind} (compiled bindings) is supported. If the project uses NativeAOT, use {x:Bind} exclusively.
  • Use x:Load or x:DeferLoadStrategy for UI elements that are not immediately needed.
  • Use ItemsRepeater with virtualization for large lists.
  • Avoid deep layout nesting — prefer Grid over nested StackPanel chains.
  • Use async/await for all I/O; never block the UI thread.

App Settings (Packaged vs Unpackaged)

  • Packaged apps: ApplicationData.Current.LocalSettings works as expected.
  • Unpackaged apps: Use a custom settings file (e.g., JSON in Environment.GetFolderPath(SpecialFolder.LocalApplicationData)).
  • Do not assume ApplicationData is always available — check packaging status first.

Typography

  • Always use built-in TextBlock styles (CaptionTextBlockStyle, BodyTextBlockStyle, BodyStrongTextBlockStyle, SubtitleTextBlockStyle, TitleTextBlockStyle, TitleLargeTextBlockStyle, DisplayTextBlockStyle).
  • Prefer using the built-in TextBlock styles over hardcoding FontSize, FontWeight, or FontFamily.
  • Font: Segoe UI Variable is the default — do not change it.
  • Use sentence casing for all UI text.

Theming & Colors

  • Always use {ThemeResource} for brushes and colors to support Light, Dark, and High Contrast themes automatically.
  • Never hardcode color values (#FFFFFF, Colors.White, etc.) for UI elements. Use theme resources like TextFillColorPrimaryBrush, CardBackgroundFillColorDefaultBrush, CardStrokeColorDefaultBrush.
  • Use SystemAccentColor (and Light1Light3, Dark1Dark3 variants) for the user's accent color palette.
  • For borders: use CardStrokeColorDefaultBrush or ControlStrokeColorDefaultBrush.

Spacing & Layout

  • Use a 4px grid system: all margins, padding, and spacing values must be multiples of 4px.
  • Standard spacing: 4 (compact), 8 (controls), 12 (small gutters), 16 (content padding), 24 (large gutters).
  • Prefer Grid over deeply nested StackPanel chains for performance.
  • Use Auto for content-sized rows/columns, * for proportional sizing. Avoid fixed pixel sizes.
  • Use VisualStateManager with AdaptiveTrigger for responsive layouts at breakpoints (640px, 1008px).
  • Use ControlCornerRadius (4px) for small controls and OverlayCornerRadius (8px) for cards, dialogs, flyouts.

Materials & Elevation

  • Use Mica (MicaBackdrop) for the app window backdrop. Requires transparent layers above to show through.
  • Use Acrylic for transient surfaces only (flyouts, menus, navigation panes).
  • Use LayerFillColorDefaultBrush for content layers above Mica.
  • Use ThemeShadow with Z-axis Translation for elevation. Cards: 48 px, Flyouts: 32 px, Dialogs: 128 px.

Motion & Transitions

  • Use built-in theme transitions (EntranceThemeTransition, RepositionThemeTransition, ContentThemeTransition, AddDeleteThemeTransition).
  • Avoid custom storyboard animations when a built-in transition exists.

Control Selection

  • Use NavigationView for primary app navigation (not custom sidebars).
  • Use InfoBar for persistent in-app notifications (not custom banners).
  • Use TeachingTip for contextual guidance (not custom popups).
  • Use NumberBox for numeric input (not TextBox with manual validation).
  • Use ToggleSwitch for on/off settings (not CheckBox).
  • Use ItemsView as the modern collection control for displaying data with built-in selection, virtualization, and layout flexibility.
  • Use ListView/GridView for standard virtualized lists and grids, especially when built-in selection support is needed.
  • Use ItemsRepeater only for fully custom virtualizing layouts where you need complete control over rendering and do not need built-in selection or interaction handling.
  • Use Expander for collapsible sections (not custom visibility toggling).

Error Handling

  • Always wrap async void event handlers in try/catch to prevent unhandled crashes.
  • Use InfoBar (with Severity = Error) for user-facing error messages, not ContentDialog for routine errors.
  • Handle App.UnhandledException for logging and graceful recovery.

Testing

  • NEVER use a plain MSTest or xUnit project for tests that instantiate WinUI 3 XAML types. Use a Unit Test App (WinUI in Desktop) project, which provides the Xaml runtime and UI thread.
  • Use [TestMethod] for pure logic tests. Use [UITestMethod] for any test that creates or interacts with Microsoft.UI.Xaml types (controls, pages, user controls).
  • Place testable business logic in a Class Library (WinUI in Desktop) project, separate from the main app.
  • Build the solution before running tests to enable Visual Studio test discovery.

Resources & Localization

  • Store user-facing strings in Resources.resw files, not in code or XAML literals.
  • Use x:Uid in XAML for localized text binding.
  • Use DPI-qualified image assets (logo.scale-200.png); reference without scale qualifier (ms-appx:///Assets/logo.png).