Migrieren einer UWP-App zu WinUI 3

UWP befindet sich nicht mehr in der aktiven Entwicklung. WinUI 3 und die Windows App SDK sind ihre Nachfolger – und KI-Tools können die meisten Migrationen automatisieren. Die wichtigste Herausforderung besteht darin, dass KI-Modelle auf Jahren von UWP-Beispielen trainiert wurden. Ohne Anleitungen reproduzieren sie also die Muster, von denen Sie sich wegbewegen möchten. Diese Seite gibt Ihrem Agenten den Kontext, den er benötigt, um es richtig zu machen.

Installieren des WinUI-Agent-Plug-Ins

Der winui-uwp-migration Skill übernimmt die gängigen Ersetzungen automatisch:

gh copilot plugin install winui@awesome-copilot

Ausführliche Informationen finden Sie im WinUI-Agent-Plug-In .

API-Ersetzungstabelle

In den folgenden Tabellen sind die am häufigsten verwendeten API-Ersetzungen zusammengefasst. Die vollständige detaillierte Zuordnung , einschließlich Membern, Eigenschaften und weniger gängigen APIs, finden Sie unter Zuordnen von UWP-APIs und -Bibliotheken zum Windows App SDK.

Important

x:Bind Standardmäßig wird der OneTime Modus verwendet. Anders als {Binding} (standardeinstellung) OneWaywird x:Bind nur einmal ausgewertet, es sei denn, Sie geben an Mode=OneWay , oder Mode=TwoWay. Prüfen Sie während der Migration alle x:Bind-Ausdrücke, die an Eigenschaften gebunden sind, die sich zur Laufzeit ändern — fehlende Mode=OneWay verursachen Fehler der Art „Die UI wird nicht aktualisiert“, die zur Kompilierzeit nicht sichtbar sind.

Namespaces

UWP WinUI 3
Windows.UI.Xaml.* Microsoft.UI.Xaml.*
Windows.UI.Xaml.Controls.* Microsoft.UI.Xaml.Controls.*
Windows.UI.Xaml.Media.* Microsoft.UI.Xaml.Media.*
Windows.UI.Composition Microsoft.UI.Composition

Threading

UWP WinUI 3
CoreDispatcher DispatcherQueue
Dispatcher.RunAsync(...) DispatcherQueue.TryEnqueue(...)
CoreApplication.MainView.CoreWindow.Dispatcher this.DispatcherQueue (von a Window oder Page)

Windowing

UWP WinUI 3
ApplicationView AppWindow
ApplicationView.GetForCurrentView() AppWindow.GetFromWindowId(...)
ApplicationViewTitleBar AppWindowTitleBar
CoreWindow Microsoft.UI.Xaml.Window
SystemNavigationManager Schaltfläche "Zurück" über AppWindowTitleBar

Dialogfelder und Auswahlfelder

UWP WinUI 3
MessageDialog ContentDialog (festlegen XamlRoot)
FileOpenPicker FileOpenPicker + InitializeWithWindow
FileSavePicker FileSavePicker + InitializeWithWindow
FolderPicker FolderPicker + InitializeWithWindow

Important

Picker erfordern InitializeWithWindow, bevor PickSingleFileAsync (oder Ähnliches) aufgerufen wird:

var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);

ContentDialog erfordert XamlRoot (nicht InitializeWithWindow):

var dialog = new ContentDialog { XamlRoot = this.Content.XamlRoot, ... };
await dialog.ShowAsync();

Benachrichtigungen

UWP WinUI 3
Windows.UI.Notifications.ToastNotificationManager Microsoft.Windows.AppNotifications.AppNotificationManager
Windows.UI.Notifications.BadgeUpdateManager Microsoft.Windows.BadgeNotifications.BadgeNotificationManager
Windows.UI.Notifications.TileUpdateManager Kacheln sind veraltet – Verwenden von Benachrichtigungen oder Widgets

Netzwerk und HTTP

UWP WinUI 3 (empfohlen)
Windows.Web.Http.HttpClient System.Net.Http.HttpClient (portierbar, keine WinRT-Abhängigkeit)
Windows.Web.Syndication.SyndicationClient System.ServiceModel.Syndication.SyndicationFeed + HttpClient
Windows.Web.AtomPub.AtomPubClient System.ServiceModel.Syndication oder direktes HTTP

Note

Die WinRT-HTTP-APIs (Windows.Web.Http) funktionieren weiterhin in verpackten WinUI 3-Apps, aber die .NET Entsprechungen werden für Portabilität, einfacheres Debuggen und umfassendere Ökosystemunterstützung (Middleware, DI, Mocking) empfohlen.

UWP WinUI 3
Frame.Navigate(typeof(MyPage)) Frame.Navigate(typeof(MyPage)) — unverändert
SystemNavigationManager.BackRequested Über NavigationView oder AppWindow verarbeiten
Windows.UI.Core.Preview.SystemNavigationManagerPreview AppWindow.Closing-Ereignis

Note

Benutzerdefinierte Hamburger-Navigation (SplitView + NavMenuListView): Viele UWP-Beispiele implementierten die Navigation mithilfe eines angepassten AppShell.xaml mit SplitView und einem selbst erstellten NavMenuListView-Steuerelement (~500+ Zeilen). Ersetzen Sie in WinUI 3 dieses gesamte Muster durch NavigationView, das die gleiche UX mit integrierter Barrierefreiheit, reaktionsfähigem Verhalten und Unterstützung für Die Zurück-Schaltfläche bietet. Dies ist in der Regel eine 80% Codereduzierung.

MVVM-Muster

UWP (allgemeine benutzerdefinierte Implementierungen) WinUI 3 (empfohlen)
Benutzerdefinierte BindableBase / ObservableObject CommunityToolkit.Mvvm.ComponentModel.ObservableObject
Benutzerdefinierte DelegateCommand / RelayCommand CommunityToolkit.Mvvm.Input.RelayCommand
Manuell SetProperty + OnPropertyChanged [ObservableProperty] Quellgenerator
Benutzerdefiniert INavigationService Integriert Frame.Navigate + NavigationView

Tip

Das CommunityToolkit.Mvvm NuGet-Paket ist die empfohlene MVVM-Foundation für WinUI 3-Apps. Es ersetzt selbst geschriebene Basisklassen durch getestete, quellcodegenerierte Entsprechungen – und eliminiert damit Hunderte von Zeilen Boilerplate-Code.

dotnet add package CommunityToolkit.Mvvm

App-Lebenszyklus

UWP WinUI 3
Application.Current.Suspending Microsoft.Windows.AppLifecycle (erfordert Architekturänderungen — siehe Hinweis)
Application.Current.Resuming AppInstance.GetCurrent().Activated (siehe Hinweis)
BackgroundTaskBuilder Windows App SDK Hintergrundaufgaben

Note

WinUI 3-App-Lebenszyklusmigration ist kein einfacher API-Namenstausch. Die Windows App SDK verwendet ein anderes Aktivierungs- und Anhaltemodell. Behandeln Sie Lebenszykluscode als etwas, das eine eigene Überarbeitung erfordert, statt ihn automatisiert zu ersetzen. Informationen zum vollständigen Modell finden Sie in der Windows App SDK-Lifecycle-Dokumentation.

Einstellungen und Speicher

UWP WinUI 3 (verpackt) WinUI 3 (entpackt)
ApplicationData.Current.LocalSettings Unverändert ❌ Auslöst einen Fehler – keine Paketidentität
ApplicationData.Current.LocalFolder Unverändert ❌ Auslöst einen Fehler – keine Paketidentität
Windows.Storage.KnownFolders Unverändert ❌ Auslöst einen Fehler – keine Paketidentität

Warning

Nicht verpackte Apps können ApplicationData.Current nicht verwenden – es kommt zur Laufzeit zu einem Fehler, da keine Paketidentität vorhanden ist. Verwenden Sie stattdessen Standard-.NET-Datei-APIs:

var appData = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
    "YourAppName");
Directory.CreateDirectory(appData);
var json = JsonSerializer.Serialize(data);
await File.WriteAllTextAsync(Path.Combine(appData, "settings.json"), json);

Note

Wenn Ihre UWP-App DataContractSerializer mit [DataMember]/[IgnoreDataMember] verwendet hat, sollten Sie eine Migration zu System.Text.Json in Betracht ziehen (schneller, kleiner, Unterstützung für Quellcodegenerierung). Die Attributzuordnung lautet:

  • [DataMember][JsonPropertyName("name")] (oder einfach Eigenschaftsnamen direkt verwenden)
  • [IgnoreDataMember][JsonIgnore]
  • [DataContract] → Keine Entsprechung erforderlich (System.Text.Json serialisiert standardmäßig öffentliche Eigenschaften)

APIs, die sich nicht ändern

Windows.Devices.*, Windows.Media.*, Windows.UI.ViewManagement.UISettings, Windows.UI.Color und die meisten WinRT-APIs außerhalb des XAML-Namespaces bleiben unverändert.

Steuerelemente ohne direkte Entsprechung

Einige UWP-Steuerelemente sind in WinUI 3 nicht vorhanden. Wählen Sie einen Ersatz basierend auf Ihrem Szenario aus:

UWP-Steuerelement WinUI 3-Ersatz Hinweise
Pivot TabView, NavigationView (oberer Modus) oder RadioButtons + Sichtbarkeit Für 2–3 feste Registerkarten ist RadioButtons mit Visibility-Umschaltung am einfachsten. Verwenden Sie für dynamische/schließbare Registerkarten TabView.
InkToolbar (benutzerdefinierte Unterklasse) CommandBar mit AppBarToggleButton Elementen Das integrierte InkToolbar ist vorhanden, doch benutzerdefinierte Unterklassenmuster lassen sich nicht sauber umsetzen. Erstellen Sie benutzerdefinierte Symbolleisten mithilfe von CommandBar neu.
RadialController WinRT-Interoperabilität mit Fenster-Handle RadialController.CreateForCurrentView() hat keine direkte Entsprechung. Verwenden Sie RadialControllerInterop mit GetForWindow(hwnd).
SystemNavigationManager Benutzerdefinierte Schaltfläche "Zurück" oder NavigationView.IsBackEnabled SystemNavigationManager.GetForCurrentView() ist nicht vorhanden. Fügen Sie Ihre eigene Zurück-Schaltfläche hinzu oder verwenden Sie die in NavigationView integrierte Zurück-Schaltfläche.

Ink, Win2D und Druck

Für diese Subsysteme sind bestimmte Migrationsschritte erforderlich, die über Namespaceänderungen hinausgehen.

Windows Ink

Die InkCanvas- und InkPresenter-APIs werden nach Microsoft.UI.Input.Inking verschoben, sind aber ansonsten identisch. Die eine nicht offensichtliche Änderung lautet CoreInputDeviceTypes:

UWP WinUI 3
Windows.UI.Input.Inking.* Microsoft.UI.Input.Inking.*
Windows.UI.Core.CoreInputDeviceTypes Microsoft.UI.Core.CoreInputDeviceTypes

InkStrokeContainer.SaveAsync() und LoadAsync() erfordern weiterhin IRandomAccessStream. Brücke aus System.IO-Streams:

// Saving ink strokes to a file using System.IO
using var memoryStream = new MemoryStream();
using var ras = memoryStream.AsRandomAccessStream();
await inkStrokeContainer.SaveAsync(ras);
await File.WriteAllBytesAsync(filePath, memoryStream.ToArray());

// Loading ink strokes from a file
var bytes = await File.ReadAllBytesAsync(filePath);
using var ms = new MemoryStream(bytes);
using var ras = ms.AsRandomAccessStream();
await inkStrokeContainer.LoadAsync(ras);

Win2D

Der Name des Win2D-Pakets wurde geändert, die API-Oberfläche ist jedoch identisch:

UWP WinUI 3
Win2D.uwp (NuGet) Microsoft.Graphics.Win2D (NuGet)

Alle Microsoft.Graphics.Canvas.* APIs (CanvasDevice, CanvasBitmap, CanvasRenderTarget, DrawInk) funktionieren auf die gleiche Weise. Nur der NuGet-Paketverweis muss aktualisiert werden.

Druck

UWP-Druck verwendet PrintManager.GetForCurrentView(). WinUI 3 erfordert die Interoperabilität mit Fensterhandles:

// UWP
var printManager = PrintManager.GetForCurrentView();
printManager.PrintTaskRequested += OnPrintTaskRequested;
await PrintManager.ShowPrintUIAsync();

// WinUI 3 — must pass window handle
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
var printManager = PrintManagerInterop.GetForWindow(hwnd);
printManager.PrintTaskRequested += OnPrintTaskRequested;
await PrintManagerInterop.ShowPrintUIForWindowAsync(hwnd);

Die PrintDocument Rendering-APIs (Paginate, GetPreviewPage, AddPages) sind unverändert.

Important

Wenn Sie das Fenster-Handle weglassen, löst PrintManagerInterop.GetForWindow einen COMException-Fehler aus. Dies ist dasselbe Interoperabilitätsmuster wie FileOpenPicker – jede API, die in UWP GetForCurrentView() verwendet hat, benötigt in WinUI 3 ein Fensterhandle.

Startaufforderung

I'm migrating a UWP app to WinUI 3 using the Windows App SDK.

Apply these substitutions:
- Windows.UI.Xaml.* → Microsoft.UI.Xaml.*
- CoreDispatcher / Dispatcher.RunAsync → DispatcherQueue.TryEnqueue
- ApplicationView → AppWindow + AppWindowTitleBar
- CoreWindow → Microsoft.UI.Xaml.Window
- MessageDialog → ContentDialog (set XamlRoot, not InitializeWithWindow)
- FileOpenPicker / FileSavePicker / FolderPicker → add InitializeWithWindow
- Windows.UI.Notifications → Microsoft.Windows.AppNotifications
- SystemNavigationManager.BackRequested → NavigationView back handling
- Pivot → TabView, NavigationView (top mode), or RadioButtons (no direct equivalent)
- InkToolbar custom subclasses → rebuild as CommandBar with AppBarToggleButton
- PrintManager.GetForCurrentView → PrintManagerInterop.GetForWindow(hwnd)
- Win2D.uwp NuGet → Microsoft.Graphics.Win2D NuGet
- Windows.UI.Input.Inking.* → Microsoft.UI.Input.Inking.*

Do not use any Windows.UI.Xaml.* namespaces in new code.
Do not use CoreDispatcher — use DispatcherQueue.
x:Bind defaults to Mode=OneTime. Add Mode=OneWay for any binding that should update at runtime.
Flag any APIs without a direct WinUI 3 equivalent rather than guessing.

Änderungen an der Projektdatei

Ersetzen Sie das UWP-Zielframework:

<!-- Before (UWP) -->
<TargetPlatformVersion>10.0.19041.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>

<!-- After (WinUI 3) -->
<TargetFramework>net10.0-windows10.0.19041.0</TargetFramework>
<WindowsSdkPackageVersion>10.0.19041.31</WindowsSdkPackageVersion>

Fügen Sie das Windows App SDK-Paket hinzu:

dotnet add package Microsoft.WindowsAppSDK