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
Anpassad 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 ❌ Genererar – 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.
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

WinUI innehåller InkCanvas, InkToolbaroch InkPresenter som experimentella API:er i experimentella versioner av Windows App SDK. De ingår inte i stabila utgåvor. Information om installation, anpassning av verktygsfält och kända begränsningar finns i Inmatningskontroller med pennstöd för WinUI-appar.

I experimentella versioner finns kontrollerna och de typer som bearbetar pennindata i Microsoft.UI.Xaml.Controls-namnområdet. Linjer och ritattribut finns kvar i Windows.UI.Input.Inking:

UWP WinUI 3 (experimentella versioner)
Windows.UI.Xaml.Controls.InkCanvas, InkToolbar, och de andra InkToolbar* typerna Microsoft.UI.Xaml.Controls, samma typnamn. Vissa medlemmar skiljer sig åt.
Windows.UI.Input.Inking.InkPresenter, InkInputConfiguration, InkInputProcessingConfiguration, InkInputProcessingMode, InkInputRightDragAction, InkStrokesCollectedEventArgs, InkHighContrastAdjustment, InkSynchronizer, InkUnprocessedInput, InkStrokeInput, InkStrokeContainer, InkStrokesErasedEventArgs Microsoft.UI.Xaml.Controls, samma typnamn. Vissa medlemmar skiljer sig åt.
Windows.UI.Input.Inking.InkStroke, InkDrawingAttributes, InkPoint, InkStrokeBuilder, InkPersistenceFormat, PenTipShape Ingen ändring
Windows.UI.Core.CoreInputDeviceTypes Ingen ändring

Varje UWP-typ i de två första raderna har en motsvarighet med samma namn, men Windows App SDK 2.5.4-experimental innehåller inte alla deras medlemmar:

  • InkStrokeContainer har ingen offentlig konstruktor och InkPresenter.StrokeContainer är skrivskyddad. Om du vill växla mellan uppsättningar med streck sparar du varje uppsättning med SaveAsync och återställer den med LoadAsync, vilket ersätter de aktuella strecken.
  • SaveAsync och LoadAsync returnerar IAsyncAction, så att de inte rapporterar förlopp och SaveAsync returnerar inte antalet byte som skrevs.
  • InkStrokeContainer.GetRecognitionResults, InkStrokeContainer.UpdateRecognitionResultsoch InkInputConfiguration.IsPenHapticFeedbackEnabled är inte tillgängliga.
  • InkToolbarRulerButton.Ruler och händelsen InkToolbar.IsRulerButtonCheckedChanged är inte tillgängliga. UWP har fasats ut till förmån för InkToolbarStencilButton, så använd stencilknappen och händelsen InkToolbar.IsStencilButtonCheckedChanged i stället.

Windows App SDK 2.4.1-experimental lade till raderings-API:er, såsom InkToolbarEraserButton.SelectedEraser och InkToolbarEraserKind, som 2.5.4-experimental tog bort. De ingick aldrig i UWP, så lägg inte till dem i migrerad kod. Den fullständiga listan finns i Ändringar från 2.4.1-experimental.

Eftersom typer som InkPresenter och InkStrokeContainer finns i båda namnrymderna, orsakar import av båda Microsoft.UI.Xaml.Controls och Windows.UI.Input.Inking felet CS0104 när du använder dessa namn. Importera Microsoft.UI.Xaml.Controlsoch lägg till aliasdirektiv för de Windows.UI.Input.Inking typer som du använder:

using Microsoft.UI.Xaml.Controls;
using InkDrawingAttributes = Windows.UI.Input.Inking.InkDrawingAttributes;
using InkStroke = Windows.UI.Input.Inking.InkStroke;

InkStrokeContainer.SaveAsync skriver till en IOutputStream, och LoadAsync läser från en IInputStream. Om du vill använda System.IO filströmmar konverterar du dem med AsOutputStream och AsInputStream. Filen måste using System; invänta dessa Windows Runtime metoder, tillsammans med using System.IO; och using Windows.Storage.Streams;:

// Save ink strokes to a file.
using (FileStream fileStream = File.Create(filePath))
using (IOutputStream output = fileStream.AsOutputStream())
{
    await inkStrokeContainer.SaveAsync(output);
    await output.FlushAsync();
}

// Load ink strokes from a file.
using (FileStream fileStream = File.OpenRead(filePath))
using (IInputStream input = fileStream.AsInputStream())
{
    await inkStrokeContainer.LoadAsync(input);
}

Du kan fortsätta att ansluta verktygsfältet till arbetsytan med InkToolbar.TargetInkCanvaseller ställa in TargetInkPresenter för att ansluta det direkt till en InkPresenter. Om du vill lägga till egna verktyg i verktygsfältet använder du InkToolbarCustomToolButton och InkToolbarCustomToggleButton, som du ser i Anpassa verktygsfältet för pennanteckning. Innan du migrerar bör du granska de kända begränsningarna, till exempel rapporterade problem med linjalen och gradmallarna.

Om din app måste använda en stabil version finns det ingen inbyggd inmatningskontroll för pennskrift att migrera till. Rendera linjer med Win2D och hantera pekarindata själv, eller använd ett pennanteckningsbibliotek från tredje part. Om du vill ersätta InkToolbaranvänder du en CommandBar med AppBarToggleButton objekt.

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)
- InkCanvas, InkToolbar, InkPresenter, InkStrokeContainer, and the other ink input types → Microsoft.UI.Xaml.Controls (experimental Windows App SDK releases only; if the project uses a stable release, flag them instead)
- Ink members that Windows App SDK 2.5.4-experimental doesn't include (new InkStrokeContainer(), assignments to InkPresenter.StrokeContainer, GetRecognitionResults, UpdateRecognitionResults, IsPenHapticFeedbackEnabled, InkToolbarRulerButton.Ruler, IsRulerButtonCheckedChanged, and progress or byte counts from SaveAsync and LoadAsync) → flag them
- PrintManager.GetForCurrentView → PrintManagerInterop.GetForWindow(hwnd)
- Win2D.uwp NuGet → Microsoft.Graphics.Win2D NuGet
- InkStroke, InkDrawingAttributes, InkPoint, InkStrokeBuilder → no change (Windows.UI.Input.Inking; use using aliases to avoid CS0104)

Do not use any Windows.UI.Xaml.* namespaces in new code.
Do not use CoreDispatcher — use DispatcherQueue.
Do not add InkToolbarEraserKind, SelectedEraser, or other eraser APIs from Windows App SDK 2.4.1-experimental. Version 2.5.4-experimental removed them.
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