# Winui3 Msix

> WinUI 3 binding gotchas, MSIX packaging, WinAppSDK test architecture, and deployment patterns

- Skill: `gabrielmoreira/winui3-msix` (Agent Skill)
- Install (CLI): `npx skillmds@latest add gabrielmoreira/winui3-msix`
- Raw SKILL.md: https://api.skillmd.com/api/skills/gabrielmoreira/winui3-msix/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: gabrielmoreira (https://skillmd.com/u/gabrielmoreira)
- Updated: 2026-09-09
- Page: https://skillmd.com/skills/gabrielmoreira/winui3-msix

---


When working on projects related to winui 3 / msix patterns, apply this domain knowledge.

# WinUI 3 / MSIX / WinAppSDK — Domain Knowledge

## Data Binding (CRITICAL — many subtle bugs)

### {x:Bind} vs {Binding}
- `{x:Bind}` in DataTemplates CRASHES with E_NOINTERFACE when used with CommunityToolkit.Mvvm
  source-generated [ObservableProperty] fields (CsWinRT marshalling issue, MVVMTK0045 warning).
- `{Binding}` works ONLY with the `[Bindable]` attribute (Microsoft.UI.Xaml.Data) on ViewModel classes.
  This enables reflection-based binding with INotifyPropertyChanged.
- `[GeneratedBindableCustomProperty]` (WinRT) generates ICustomPropertyProvider but does NOT wire up
  INotifyPropertyChanged — only reads initial values, no live updates.
- `{Binding Command}` does NOT work for page-level buttons (only inside DataTemplates where
  DataContext is the VM) — use Click handlers with code-behind instead.
- Suppress MVVMTK0045 via NoWarn (field-based [ObservableProperty] not AOT-safe for x:Bind,
  but acceptable when using {Binding}).

### Layout Gotchas
- GridView/ItemsWrapGrid: ItemsPanelRoot is null when control is Collapsed.
  SizeChanged events have timing issues.
- UniformGridLayout in ItemsRepeater doesn't stretch items to fill parent width.
- Solution for horizontal card layouts: manually create cards via DataTemplate.LoadContent(),
  compute Width in code-behind on SizeChanged.

## MSIX Packaging

### EnableMsixTooling
- Set `<EnableMsixTooling>true</EnableMsixTooling>` — generates AppxManifest.xml in output dir
  (not AppX subdir like traditional packaging).
- Set `WindowsAppSdkDeploymentManagerInitialize=false` for loose-file registration.
- resources.pri filename is auto-generated by EnableMsixTooling; MSIX runtime expects lowercase.

### Package.appxmanifest
- Require `uap10:TrustLevel="mediumIL"` and `uap10:RuntimeBehavior="packagedClassicApp"`.
- ProcessorArchitecture must match actual target (x64/arm64), NOT "neutral".
- Framework dependency on WindowsAppRuntime must match installed version.

### Building
- WinUI 3 apps may require VS MSBuild (not `dotnet build`) due to MSIX packaging tasks.
- Use `-p:WindowsPackageType=None` for architecture-neutral builds/tests without packaging.
- The WindowsAppSDK package injects auto-initializer source files — exclude them in test projects:
  `<Compile Remove="**\\*AutoInitializer*.cs" />`

## Test Architecture for WinUI 3 Apps
- Do NOT add a project reference from the test project to the WinUI app project.
  The WinAppSDK module auto-initializer .cctor will crash in a test context.
- Instead, compile source files directly: `<Compile Include="..\\Models\\*.cs" />`
- Set `WindowsAppSdkAutoInitialize=false` in the test csproj.
- Set `AllowUnsafeBlocks=true` (required by LibraryImport generated code).
- Create fake/mock implementations of native client interfaces for testability.

## DI Pattern
- `App.Services` = IServiceProvider from ServiceCollection.
- Register singletons for native client wrappers, ViewModels.
- Views resolve via `App.Services.GetRequiredService<T>()`.
- Constructor injection for ViewModels taking native interfaces.

## MSIX Deployment (Loose-File / Sideload)
- `Add-AppxPackage -Register <manifest-path>` for local registration.
- `WinAppDeployCmd`: use `deployfiles` (copies files) then `registerfiles` (registers on device).
- Deploy.ps1 pattern: auto-detect MSBuild via vswhere, detect OS architecture,
  build with WindowsPackageType=None, assemble layout, register.

