agentleFS
MicrosoftKnown publishermicrosoft/winappCli/plugins/winui/agent-plugin/skills/winui-wpf-migration/SKILL.md

winui-wpf-migration

Skill1.4k starsChanged 55 days agoMITView on GitHub

Migrate or port a WPF app to WinUI 3: namespaces (System.Windows to Microsoft.UI.Xaml), control mapping (DataGrid, WrapPanel, TabControl), Dispatcher to DispatcherQueue, imaging, MVVM with CommunityToolkit.Mvvm, ThemeResource. Use when converting WPF code or fixing migration build errors.

1 other project uses a version of this, 1 of them edited.

Adopted by

Steady: 0 new projects took it in the last 4 weeks, none the 4 weeks before.thin data

Week of Sep 13: 0 new projectsWeek of Sep 20: 0 new projectsWeek of Sep 27: 0 new projectsWeek of Oct 4: 0 new projectsWeek of Oct 11: 0 new projectsWeek of Oct 18: 0 new projectsWeek of Oct 25: 0 new projectsWeek of Nov 1: 0 new projects
Sep 2026Oct 2026Nov 2026
New projects taking a version of this file each week, over the 8 weeks our latest run read: only 0 in all, so this is a hint, not a trend.

Most recently taken up by

Who's talking about microsoft/winappCli

The biggest 5 of 52 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 52

Talked about on GitHub, Bluesky and Stack Overflow (52 times).

On GitHub · 50

45 more on GitHub

On Bluesky · 1

On Stack Overflow · 1

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 3 are distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use the WinApp CLI 0.7+ prerequisites and per-app analyzer setup in winui-dev-workflow.

    line 8
  2. Distinctive:

    Before writing code, inventory WPF-specific APIs:

    line 11
  3. Distinctive:

    Before implementing API replacements, restore the app project and check its exact references from the WinUI project directory, not the old …

    line 24
  4. Very specific:

    Use winapp find-ui "<intent>" for usage samples.

    line 30
  5. Very specific:

    Remove ALL System.Windows.Media.Imaging references at migration start

    line 68
  6. Very specific:

    Do NOT add <UseWPF>true</UseWPF> — it silently corrupts the build

    line 70
  7. Distinctive:

    If heavy imaging code exists, migrate it early (step 2, not step 7)

    line 71
  8. Very specific:

    Delete custom ObservableObject/RelayCommand/DelegateCommand.

    line 74
  9. Very specific:

    Prefer {x:Bind} for known types.

    line 77
  10. Very specific:

    Keep packaged as the default.

    line 89

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Migration Process

Use the WinApp CLI 0.7+ prerequisites and per-app analyzer setup in winui-dev-workflow. The normal SDK path needs .NET 8.0.100 or later and the SDK required by the target TFM; Native AOT additionally needs MSVC/Desktop C++ tools. Handle missing prerequisites as described there.

Step 1: Audit the WPF Source

Before writing code, inventory WPF-specific APIs:

# Find all WPF namespace usage
Select-String -Path (Get-ChildItem -Recurse -Filter "*.cs" | Where-Object { $_.FullName -notlike "*\obj\*" }) -Pattern "System\.Windows\." | Select-Object -Property Filename, LineNumber, Line

List: WPF controls used, custom MVVM framework, imaging APIs, threading patterns, Win32 interop.

Step 2: Create WinUI 3 Project and Align Namespaces

winapp new --name <AppName> --template winui-mvvm --template-version latest --use-defaults

Immediately set <RootNamespace> in .csproj to match the WPF namespace. Update x:Class in App.xaml, MainWindow.xaml and their code-behind files. Add the analyzer per winui-dev-workflow. Build to verify before porting any code.

Before implementing API replacements, restore the app project and check its exact references from the WinUI project directory, not the old WPF project or machine SDK:

winapp find-api DispatcherQueue --json --project-dir .
winapp find-api members DispatcherQueue --filter TryEnqueue --json --project-dir .
winapp find-api check-property ListView ItemsSource SelectionMode --json --project-dir .

Use winapp find-ui "<intent>" for usage samples; see winui-design for project selection and batch API checks.

Step 3: Replace Namespaces

WPFWinUI 3
System.WindowsMicrosoft.UI.Xaml
System.Windows.ControlsMicrosoft.UI.Xaml.Controls
System.Windows.MediaMicrosoft.UI.Xaml.Media
System.Windows.InputMicrosoft.UI.Xaml.Input
System.Windows.DataMicrosoft.UI.Xaml.Data
System.Windows.Threading.DispatcherMicrosoft.UI.Dispatching.DispatcherQueue
PresentationCore / PresentationFrameworkRemove entirely

Step 4: Replace Controls

WPF ControlWinUI 3 Equivalent
DataGridListView with Grid column headers
WrapPanelItemsRepeater + UniformGridLayout
TabControlTabView
StatusBarGrid row at bottom with TextBlock elements
Menu / MenuItemMenuBar / MenuBarItem / MenuFlyoutItem
ToolBarCommandBar
Expander (custom)Expander (built-in)

Step 5: Replace Threading

// WPF
Application.Current.Dispatcher.Invoke(() => { /* UI work */ });

// WinUI 3
dispatcherQueue.TryEnqueue(() => { /* UI work */ });

Get via DispatcherQueue.GetForCurrentThread(). No Application.Current.Dispatcher in WinUI 3.

Step 6: Replace Imaging

Critical: PresentationCore.dll and System.Windows.Media.Imaging crash the WinUI XAML compiler. This is an architectural incompatibility — no workaround exists.

  • Remove ALL System.Windows.Media.Imaging references at migration start
  • Replace with Windows.Graphics.Imaging (WinRT) or Microsoft.UI.Xaml.Media.Imaging.BitmapImage
  • Do NOT add <UseWPF>true</UseWPF> — it silently corrupts the build
  • If heavy imaging code exists, migrate it early (step 2, not step 7)

Step 7: Replace MVVM Framework

Delete custom ObservableObject/RelayCommand/DelegateCommand. Use CommunityToolkit.Mvvm:

  • INotifyPropertyChanged base → ObservableObject with [ObservableProperty] partial properties (fix MVVMTK0045; don't keep fields)
  • Custom RelayCommand → [RelayCommand] attribute
  • Prefer {x:Bind} for known types; keep runtime {Binding}/DisplayMemberPath where needed. See winui-packaging's references/sourcegen-patterns.md for binding modes, x:DataType, and AOT-safe runtime binding.
  • DynamicResource → {ThemeResource}

Step 8: Replace Resources

  • .resx → .resw (copy + rename to Strings\en-us\)
  • {x:Static} → x:Uid for localized strings
  • Properties.Resources.Key → ResourceLoader.GetString("Key")

Critical Rules

  • ❌ NEVER reference PresentationCore, PresentationFramework, or System.Windows.Controls assemblies
  • ❌ NEVER add <UseWPF>true</UseWPF>
  • Keep packaged as the default; see winui-dev-workflow Critical Rules for unpackaged experiments.
  • ❌ NEVER delete Package.appxmanifest
  • ❌ NEVER overwrite App.xaml / App.xaml.cs — merge WPF code into the WinUI 3 boilerplate
  • ✅ Launch with project-mode winapp run, not the .exe directly.
  • ✅ Break migration into file-level tasks — not one massive rewrite

Post-Migration Validation

# Check for remaining WPF references (should return nothing)
Select-String -Path (Get-ChildItem -Recurse -Filter "*.cs" | Where-Object { $_.FullName -notlike "*\obj\*" }) -Pattern "System\.Windows\."

# Verify packaging preserved
Test-Path "Package.appxmanifest"  # should be True

# Build (the analyzer participates when installed)
dotnet build .\MyApp.csproj -p:Platform=x64

# Run the migrated app
winapp run .\MyApp.csproj --detach --json

For UI validation, see winui-ui-testing; for crash diagnostics, see winui-dev-workflow. If AOT is intended, also test the published artifact via the workflow's AOT path; the run above is JIT, even in Release.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.