Migrera en UWP-app till WinUI 3

UWP är inte längre under aktiv utveckling. WinUI 3 och Windows App SDK är dess efterföljare – och AI-verktyg kan automatisera större delen av migreringen. Den största utmaningen är att AI-modeller har tränats på år av UWP-exempel, så utan vägledning återskapar de mönster som du försöker flytta bort från. Den här sidan ger din agent den kontext den behöver för att få det rätt.

Installera plugin-programmet för WinUI-agenten

Färdigheten winui-uwp-migration hanterar de vanliga ersättningarna automatiskt:

gh copilot plugin install winui@awesome-copilot

Se Plugin-programmet för WinUI-agenten för fullständig information.

API-ersättningstabell

I följande tabeller sammanfattas de vanligaste API-ersättningarna. Fullständig detaljerad mappning – inklusive medlemmar, egenskaper och mindre vanliga API:er – finns i Mappa UWP-API:er och bibliotek till Windows App SDK.

Important

x:Bind är som standard inställt på läget OneTime. Till skillnad från {Binding} (som standard är OneWay), x:Bind utvärderas bara en gång om du inte anger Mode=OneWay eller Mode=TwoWay. Vid migreringen ska du granska alla x:Bind-uttryck som är bundna till egenskaper som ändras vid körning — avsaknad av Mode=OneWay orsakar buggar av typen "gränssnittet uppdateras inte" som inte syns vid kompilering.

Namnområden

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

Trådning

UWP WinUI 3
CoreDispatcher DispatcherQueue
Dispatcher.RunAsync(...) DispatcherQueue.TryEnqueue(...)
CoreApplication.MainView.CoreWindow.Dispatcher this.DispatcherQueue (från en Window eller Page)

Windowing

UWP WinUI 3
ApplicationView AppWindow
ApplicationView.GetForCurrentView() AppWindow.GetFromWindowId(...)
ApplicationViewTitleBar AppWindowTitleBar
CoreWindow Microsoft.UI.Xaml.Window
SystemNavigationManager Bakåtknapp via AppWindowTitleBar

Dialogrutor och väljare

UWP WinUI 3
MessageDialog ContentDialog (ställ in XamlRoot)
FileOpenPicker FileOpenPicker + InitializeWithWindow
FileSavePicker FileSavePicker + InitializeWithWindow
FolderPicker FolderPicker + InitializeWithWindow

Important

Väljare kräver InitializeWithWindow innan de anropar PickSingleFileAsync (eller liknande):

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

ContentDialog kräver XamlRoot (inte InitializeWithWindow):

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

Notifications

UWP WinUI 3
Windows.UI.Notifications.ToastNotificationManager Microsoft.Windows.AppNotifications.AppNotificationManager
Windows.UI.Notifications.BadgeUpdateManager Microsoft.Windows.BadgeNotifications.BadgeNotificationManager
Windows.UI.Notifications.TileUpdateManager Paneler är inaktuella – använd meddelanden eller widgetar

Nätverk och HTTP

UWP WinUI 3 (rekommenderas)
Windows.Web.Http.HttpClient System.Net.Http.HttpClient (portabel, inget WinRT-beroende)
Windows.Web.Syndication.SyndicationClient System.ServiceModel.Syndication.SyndicationFeed + HttpClient
Windows.Web.AtomPub.AtomPubClient System.ServiceModel.Syndication eller direkt-HTTP

Note

WinRT HTTP-API:er (Windows.Web.Http) fungerar fortfarande i paketerade WinUI 3-appar, men de .NET motsvarigheterna rekommenderas för portabilitet, enklare felsökning och bredare ekosystemstöd (mellanprogram, DI, mocking).

UWP WinUI 3
Frame.Navigate(typeof(MyPage)) Frame.Navigate(typeof(MyPage)) — oförändrad
SystemNavigationManager.BackRequested Hantera via NavigationView eller AppWindow
Windows.UI.Core.Preview.SystemNavigationManagerPreview AppWindow.Closing evenemang

Note

Anpassad hamburgernavigering (SplitView + NavMenuListView): Många UWP-exempel implementerade navigering med hjälp av en anpassad AppShell.xaml med SplitView och en handvalsad NavMenuListView kontroll (~500+ rader). I WinUI 3 ersätter du hela det här mönstret med NavigationView, som ger samma UX med inbyggd tillgänglighet, responsivt beteende och stöd för bakåtknappar. Detta är vanligtvis en kodminskning på 80%.

MVVM-mönster

UWP (vanliga anpassade implementeringar) WinUI 3 (rekommenderas)
Anpassad BindableBase / ObservableObject CommunityToolkit.Mvvm.ComponentModel.ObservableObject
Anpassade DelegateCommand / RelayCommand CommunityToolkit.Mvvm.Input.RelayCommand
Manuell SetProperty + OnPropertyChanged [ObservableProperty] källgenerator
Anpassad INavigationService Inbyggd Frame.Navigate + NavigationView

Tip

NuGet-paketet CommunityToolkit.Mvvm är den rekommenderade MVVM-grunden för WinUI 3-appar. Den ersätter handrullade basklasser med testade, källgenererade motsvarigheter – vilket eliminerar hundratals linjer med pannplåt.

dotnet add package CommunityToolkit.Mvvm

Appens livscykel

UWP WinUI 3
Application.Current.Suspending Microsoft.Windows.AppLifecycle (kräver arkitekturändringar – se anmärkning)
Application.Current.Resuming AppInstance.GetCurrent().Activated (se anmärkning)
BackgroundTaskBuilder Windows App SDK bakgrundsaktiviteter

Note

WinUI 3-applivscykelmigrering är inte ett enkelt API-namnbyte. Windows App SDK använder en annan aktiverings- och fjädringsmodell. Betrakta kod för livscykelhantering som något som kräver en särskild omskrivning snarare än automatiserad ersättning. Se dokumentationen om Windows App SDK livscykel för den fullständiga modellen.

Inställningar och lagring

UWP WinUI 3 (paketerad) WinUI 3 (utan paket)
ApplicationData.Current.LocalSettings Oförändrad ❌ Genererar – ingen paketidentitet
ApplicationData.Current.LocalFolder Oförändrad ❌ Genererar – ingen paketidentitet
Windows.Storage.KnownFolders Oförändrad ❌ Utlöser — ingen paketidentitet

Varning

Opaketerade appar kan inte använda ApplicationData.Current – det ger ett undantag vid körning eftersom det inte finns någon paketidentitet. Använd standard-.NET-fil-API:er i stället:

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

Om din UWP-app använde DataContractSerializer med [DataMember]/[IgnoreDataMember], kan du överväga att migrera till System.Text.Json (snabbare, mindre, stöd för källkodsgenerering). Attributmappningen är:

  • [DataMember] [JsonPropertyName("name")] → (eller bara använda egenskapsnamn direkt)
  • [IgnoreDataMember][JsonIgnore]
  • [DataContract] → Ingen motsvarighet krävs (System.Text.Json serialiserar offentliga egenskaper som standard)

API:er som inte ändras

Windows.Devices.*, Windows.Media.*, Windows.UI.ViewManagement.UISettings, Windows.UI.Color och de flesta WinRT-API:er utanför XAML-namnområdet ändras inte.

Kontroller utan direkt motsvarighet

Vissa UWP-kontroller finns inte i WinUI 3. Välj en ersättning baserat på ditt scenario:

UWP-kontroll WinUI 3-ersättning Noteringar
Pivot TabView, NavigationView (övre läget) eller RadioButtons + synlighet För 2–3 fasta flikar RadioButtons är det enklast att byta synlighet. För dynamiska/stängbara flikar använder du TabView.
InkToolbar (anpassad underklass) CommandBar med AppBarToggleButton objekt Den inbyggda InkToolbar finns, men anpassade mönster för att skapa underklasser låter sig inte översättas på ett naturligt sätt. Återskapa anpassade verktygsfält med hjälp av CommandBar.
RadialController WinRT-samverkan med fönsterhandtag RadialController.CreateForCurrentView() har ingen direkt motsvarighet. Använd RadialControllerInterop med GetForWindow(hwnd).
SystemNavigationManager Anpassad Tillbaka-knapp eller NavigationView.IsBackEnabled SystemNavigationManager.GetForCurrentView() finns inte. Lägg till en egen bakåtknapp eller använd NavigationViewden inbyggda bakåtknappen.

Pennanteckning, Win2D och utskrift

Dessa undersystem kräver specifika migreringssteg utöver namnområdesändringar.

Windows Ink

InkCanvas API:erna och InkPresenter flyttas till Microsoft.UI.Input.Inking men är i övrigt identiska. Den enda icke-uppenbara ändringen är CoreInputDeviceTypes:

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

InkStrokeContainer.SaveAsync() och LoadAsync() kräver fortfarande IRandomAccessStream. Överbrygga från System.IO strömmar:

// 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

Win2D-paketnamnet ändrades men API-ytan är identisk:

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

Alla Microsoft.Graphics.Canvas.* API:er (CanvasDevice, CanvasBitmap, CanvasRenderTarget, DrawInk) fungerar på samma sätt. Endast NuGet-paketreferensen behöver uppdateras.

Skriva ut

UWP-utskrift använder PrintManager.GetForCurrentView(). WinUI 3 kräver samverkan med fönsterhandtag:

// 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);

Renderings-API PrintDocument :erna (Paginate, GetPreviewPage, AddPages) är oförändrade.

Important

Om du utelämnar fönsterhandtaget PrintManagerInterop.GetForWindow genererar en COMException. Det här är samma interopmönster som FileOpenPicker – alla API:er som används GetForCurrentView() i UWP behöver ett fönsterhandtag i WinUI 3.

Startprompt

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.

Ändringar i projektfilen

Ersätt UWP-målramverket:

<!-- 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>

Lägg till Windows App SDK-paketet:

dotnet add package Microsoft.WindowsAppSDK