Claude
Skills
Sign in
Back

dotnet-wpf-migration

Included with Lifetime
$97 forever

Migrating desktop apps. WPF/WinForms to .NET 8+, WPF to WinUI or Uno, UWP to WinUI, decision matrix.

General

What this skill does


# dotnet-wpf-migration

Context-dependent migration guidance for Windows desktop applications. Covers WPF .NET Framework to .NET 8+, WPF to WinUI 3 (Windows-only modernization), WPF to Uno Platform (cross-platform), WinForms .NET Framework to .NET 8+, UWP to WinUI 3, UWP to Uno Platform (cross-ref), and a decision matrix for choosing the right migration target based on project constraints.

**Version assumptions:** .NET 8.0+ baseline (current LTS). `dotnet-upgrade-assistant` for automated migration. .NET 9 features explicitly marked where applicable.

**Scope boundary:** This skill owns migration paths between desktop frameworks and from .NET Framework to modern .NET. Individual framework patterns (WPF modern, WinUI, WinForms modern) are owned by the respective framework skills. The framework selection decision tree is owned by [skill:dotnet-ui-chooser].

**Out of scope:** WPF .NET 8+ development patterns -- see [skill:dotnet-wpf-modern]. WinUI 3 development patterns -- see [skill:dotnet-winui]. WinForms .NET 8+ development patterns -- see [skill:dotnet-winforms-basics]. Uno Platform development patterns -- see [skill:dotnet-uno-platform]. Framework selection decision tree -- see [skill:dotnet-ui-chooser]. Desktop testing -- see [skill:dotnet-ui-testing-core].

Cross-references: [skill:dotnet-wpf-modern] for WPF .NET 8+ patterns, [skill:dotnet-winui] for WinUI 3 patterns, [skill:dotnet-winforms-basics] for WinForms .NET 8+ patterns, [skill:dotnet-uno-platform] for Uno Platform patterns, [skill:dotnet-ui-chooser] for framework selection, [skill:dotnet-ui-testing-core] for desktop testing.

---

## Migration Path Overview

Choose a migration path based on your current framework and target goals. Each path has different trade-offs in effort, risk, and capability gain.

| Current | Target | Effort | Risk | When to Choose |
|---|---|---|---|---|
| WPF .NET Framework | WPF .NET 8+ | Low-Medium | Low | Modernize runtime, keep existing UI |
| WPF .NET Framework | WinUI 3 | High | Medium | Modern Windows UI, touch/pen, Fluent |
| WPF .NET Framework | Uno Platform | High | Medium-High | Cross-platform needed |
| WinForms .NET Framework | WinForms .NET 8+ | Low | Low | Modernize runtime, keep existing UI |
| UWP | WinUI 3 | Medium | Medium | Stay Windows-only, modern runtime |
| UWP | Uno Platform | Medium-High | Medium | Cross-platform needed from UWP |

---

## WPF .NET Framework to .NET 8+

The lowest-risk migration path. Keeps your existing XAML and code-behind intact while moving to modern .NET with better performance, DI support, and side-by-side deployment.

### Using dotnet-upgrade-assistant

The .NET Upgrade Assistant automates the bulk of the migration:

```bash
# Install the upgrade assistant
dotnet tool install -g upgrade-assistant

# Analyze the project first (non-destructive)
upgrade-assistant analyze MyWpfApp.sln

# Upgrade the project
upgrade-assistant upgrade MyWpfApp.sln
```

**What the upgrade assistant handles:**
- `.csproj` conversion from legacy format to SDK-style
- `packages.config` to `PackageReference` migration
- TFM change to `net8.0-windows`
- `AssemblyInfo.cs` properties moved to `.csproj`
- Common API replacements and namespace updates

**What requires manual work:**
- `App.config` settings migration to `appsettings.json` or Host builder configuration
- `Settings.settings` / `My.Settings` (VB.NET) migration
- Third-party control library updates (check vendor .NET 8 compatibility)
- WCF client references (use `CoreWCF` or migrate to gRPC/REST)
- COM interop adjustments (syntax differences in `System.Runtime.InteropServices`)
- Custom MSBuild targets and build scripts

### API Compatibility

Most WPF APIs are identical between .NET Framework and .NET 8+. Key differences:

| Area | .NET Framework | .NET 8+ | Action |
|---|---|---|---|
| Clipboard | `Clipboard.SetText()` | Same API | No change |
| Printing | `PrintDialog`, `PrintVisual` | Same API | No change |
| BitmapEffect | Deprecated (software-rendered) | Removed | Use `Effect` / `ShaderEffect` |
| `DrawingContext.PushEffect` | Available | Removed | Use `ShaderEffect` |
| XPS documents | `System.Windows.Xps` | Requires NuGet package | Add `System.Windows.Xps` PackageReference |
| Speech synthesis | `System.Speech` | Requires NuGet package | Add `System.Speech` PackageReference |

### NuGet Package Updates

After migration, update NuGet packages to .NET 8-compatible versions:

```bash
# List outdated packages
dotnet list package --outdated

# Update packages (one at a time for safer migration)
dotnet add package Newtonsoft.Json --version 13.*
dotnet add package MaterialDesignThemes --version 5.*
```

**Common package replacements:**
- `Unity` container -> `Microsoft.Extensions.DependencyInjection` (built-in)
- `Autofac` -> update to latest (supports .NET 8)
- `log4net` / `NLog` -> consider `Microsoft.Extensions.Logging` with Serilog or NLog provider
- `EntityFramework` (EF6) -> `Microsoft.EntityFrameworkCore` 8.x

### Breaking Changes Checklist

- **Default high-DPI behavior changed.** .NET 8 WPF enables `PerMonitorV2` DPI awareness by default (not `SystemAware` like .NET Framework).
- **Nullable reference types.** New projects enable NRT. Existing code may produce warnings. Suppress with `<Nullable>disable</Nullable>` initially, then fix incrementally.
- **Implicit usings.** New SDK-style projects enable implicit usings. May conflict with existing `using` statements. Disable with `<ImplicitUsings>disable</ImplicitUsings>` if needed.
- **Assembly loading.** `AssemblyLoadContext` replaces `AppDomain` for assembly isolation. Plugin architectures using `AppDomain.CreateDomain` need rework.
- **Runtime behavior.** .NET 8 GC is more aggressive with Gen0/Gen1 collections. Finalizer-dependent code may behave differently.

For post-migration WPF patterns (Host builder, MVVM Toolkit, modern C#), see [skill:dotnet-wpf-modern].

---

## WPF to WinUI 3

Migrate when you need modern Windows-native UI: Fluent Design, touch/pen input, Windows 11 integration (widgets, Mica), or UWP-style APIs on modern .NET. This is a **partial rewrite** -- XAML concepts transfer but APIs and namespaces differ.

### When This Path Makes Sense

- Application is **Windows-only** and will stay Windows-only
- Need modern **Fluent Design** controls, touch/pen support, or Windows 11 features
- Team is willing to invest in **XAML rewrite** effort
- Application is **actively developed** with ongoing feature work (justifies the investment)

### When to Consider Alternatives

- If **cross-platform** is needed -> migrate to Uno Platform instead (WinUI XAML surface)
- If application is in **maintenance mode** -> migrate to WPF .NET 8+ instead (lower effort)
- If WPF Fluent theme (.NET 9+) is sufficient -> stay on WPF .NET 8+ with `ThemeMode = ThemeMode.System`

### XAML Differences

| WPF XAML | WinUI 3 XAML | Notes |
|---|---|---|
| `xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"` | Same URI (but resolves to `Microsoft.UI.Xaml` types, not `System.Windows`) | No xmlns change, but runtime types differ |
| `{Binding Path=Name}` | `{x:Bind Name, Mode=OneWay}` | Prefer `x:Bind` (compiled, type-safe) |
| `DataContext` binding | Code-behind property + `x:Bind` | `x:Bind` resolves against code-behind |
| `Window` inherits from `System.Windows.Window` | `Window` inherits from `Microsoft.UI.Xaml.Window` | Different base class and API |
| `UserControl` | `UserControl` (Microsoft.UI.Xaml namespace) | Same concept, different namespace |
| `Style` with `TargetType` | Same | Works the same way |
| `DataTemplate` | Needs `x:DataType` for `x:Bind` | Required for compiled bindings |
| `ContextMenu` | `MenuFlyout` | Different control type |
| `StatusBar` | No built-in equivalent | Use custom `CommandBar` or `InfoBar` |
| `RibbonControl` | No built-in equivalent | Use `NavigationView` + `CommandBar` |

### Migration Strategy

1. **Create a new WinUI 3 project** alongside the existing WPF project
2. **Migrate shared logic 

Related in General