Zmigruj aplikację UWP do interfejsu WinUI 3

Platforma UWP nie jest już aktywnie opracowywana. WinUI 3 i Zestaw SDK do aplikacji systemu Windows są jego następcami — a narzędzia sztucznej inteligencji mogą zautomatyzować większość migracji. Głównym wyzwaniem jest to, że modele sztucznej inteligencji zostały przeszkolone na lata próbek platformy UWP, więc bez wskazówek odtwarzają wzorce, z których próbujesz odejść. Ta strona zapewnia agentowi kontekst potrzebny do prawidłowego działania.

Instalowanie wtyczki agenta WinUI

Umiejętność winui-uwp-migration automatycznie obsługuje typowe zamiany:

gh copilot plugin install winui@awesome-copilot

Aby uzyskać szczegółowe informacje, zobacz wtyczkę agenta WinUI .

Tabela podstawiania interfejsu API

Poniższe tabele przedstawiają podsumowanie najczęstszych zamienników interfejsu API. Aby uzyskać pełne, szczegółowe mapowanie — w tym składowe, właściwości i rzadziej używane interfejsy API — zobacz Mapowanie interfejsów API i bibliotek UWP na zestaw Zestaw SDK do aplikacji systemu Windows.

Important

x:Bind domyślnie działa w trybie OneTime. W przeciwieństwie do {Binding} (które domyślnie przyjmuje wartość OneWay), x:Bind jest obliczane tylko raz, chyba że określisz Mode=OneWay lub Mode=TwoWay. Podczas migracji przejrzyj wszystkie wyrażenia x:Bind, które są wiązane z właściwościami zmieniającymi się w czasie wykonywania — brak Mode=OneWay powoduje błędy „interfejs użytkownika się nie aktualizuje”, które są niewidoczne na etapie kompilacji.

Przestrzenie nazw

platforma 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

Wątkowanie

platforma UWP WinUI 3
CoreDispatcher DispatcherQueue
Dispatcher.RunAsync(...) DispatcherQueue.TryEnqueue(...)
CoreApplication.MainView.CoreWindow.Dispatcher this.DispatcherQueue (z elementu Window lub Page)

Windowing

platforma UWP WinUI 3
ApplicationView AppWindow
ApplicationView.GetForCurrentView() AppWindow.GetFromWindowId(...)
ApplicationViewTitleBar AppWindowTitleBar
CoreWindow Microsoft.UI.Xaml.Window
SystemNavigationManager Przycisk Wstecz za pośrednictwem AppWindowTitleBar

Okna dialogowe i selektory

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

Important

Pickery wymagają użycia InitializeWithWindow przed wywołaniem PickSingleFileAsync (lub podobnego):

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

Element ContentDialog wymaga XamlRoot (a nie InitializeWithWindow):

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

Notifications

platforma UWP WinUI 3
Windows.UI.Notifications.ToastNotificationManager Microsoft.Windows.AppNotifications.AppNotificationManager
Windows.UI.Notifications.BadgeUpdateManager Microsoft.Windows.BadgeNotifications.BadgeNotificationManager
Windows.UI.Notifications.TileUpdateManager Kafelki są przestarzałe — użyj powiadomień lub widżetów

Sieć i protokół HTTP

platforma UWP WinUI 3 (zalecane)
Windows.Web.Http.HttpClient System.Net.Http.HttpClient (wersja przenośna, niewymagająca zależności od WinRT)
Windows.Web.Syndication.SyndicationClient System.ServiceModel.Syndication.SyndicationFeed + HttpClient
Windows.Web.AtomPub.AtomPubClient System.ServiceModel.Syndication lub bezpośredni protokół HTTP

Note

Interfejsy API HTTP WinRT (Windows.Web.Http) nadal działają w aplikacjach pakietowanych WinUI 3, ale ze względu na przenośność, łatwiejsze debugowanie i szersze wsparcie ekosystemu (oprogramowanie pośredniczące, DI, mockowanie) zalecane są odpowiedniki .NET.

platforma UWP WinUI 3
Frame.Navigate(typeof(MyPage)) Frame.Navigate(typeof(MyPage)) — bez zmian
SystemNavigationManager.BackRequested Obsłuż za pomocą NavigationView lub AppWindow
Windows.UI.Core.Preview.SystemNavigationManagerPreview zdarzenie AppWindow.Closing

Note

Niestandardowa nawigacja typu hamburger (SplitView + NavMenuListView): W wielu przykładach UWP zaimplementowano nawigację przy użyciu niestandardowego AppShell.xaml z SplitView oraz ręcznie napisanej kontrolki NavMenuListView (~500+ wierszy). W WinUI 3 zastąp cały ten wzorzec elementem NavigationView, który zapewnia ten sam UX dzięki wbudowanym ułatwieniom dostępu, adaptacyjnemu zachowaniu i obsłudze przycisku Wstecz. Jest to zazwyczaj 80% redukcji kodu.

Wzorce MVVM

Platforma UWP (typowe implementacje niestandardowe) WinUI 3 (zalecane)
Niestandardowe BindableBase / ObservableObject CommunityToolkit.Mvvm.ComponentModel.ObservableObject
Niestandardowe DelegateCommand / RelayCommand CommunityToolkit.Mvvm.Input.RelayCommand
Ręczny SetProperty + OnPropertyChanged [ObservableProperty] generator kodu źródłowego
Zwyczaj INavigationService Wbudowane Frame.Navigate + NavigationView

Wskazówka

Pakiet NuGet CommunityToolkit.Mvvm jest zalecaną podstawą MVVM dla aplikacji WinUI 3. Zastępuje ręcznie tworzone klasy bazowe sprawdzonymi odpowiednikami generowanymi na podstawie kodu źródłowego, co eliminuje setki linii powtarzalnego kodu.

dotnet add package CommunityToolkit.Mvvm

Cykl życia aplikacji

platforma UWP WinUI 3
Application.Current.Suspending Microsoft.Windows.AppLifecycle (wymaga zmian architektury — zobacz uwaga)
Application.Current.Resuming AppInstance.GetCurrent().Activated (patrz uwaga)
BackgroundTaskBuilder Zadania w tle Zestaw SDK do aplikacji systemu Windows

Note

Migracja cyklu życia aplikacji WinUI 3 nie jest prostą zamianą nazw interfejsu API. W Zestaw SDK do aplikacji systemu Windows jest używany inny model aktywacji i zawieszenia. Traktuj kod cyklu życia jako wymagający dedykowanego ponownego zapisywania, a nie automatycznego zastępowania. Zobacz dokumentację cyklu życia Zestaw SDK do aplikacji systemu Windows aby zapoznać się z pełnym modelem.

Ustawienia i pamięć

platforma UWP WinUI 3 (spakowane) WinUI 3 (rozpakowany)
ApplicationData.Current.LocalSettings Niezmienione ❌ Throws — brak tożsamości pakietu
ApplicationData.Current.LocalFolder Niezmienione ❌ Throws — brak tożsamości pakietu
Windows.Storage.KnownFolders Niezmienione ❌ Throws — brak tożsamości pakietu

Warning

Aplikacje bez pakietu nie mogą używać ApplicationData.Current — powoduje to wyjątek w czasie wykonywania, ponieważ aplikacja nie ma tożsamości pakietu. Zamiast tego użyj standardowych interfejsów API plików .NET:

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

Jeśli aplikacja UWP używała DataContractSerializer z [DataMember]/[IgnoreDataMember], rozważ migrację do System.Text.Json (szybsza, mniejsza, z obsługą generatorów kodu źródłowego). Mapowanie atrybutów to:

  • [DataMember] [JsonPropertyName("name")] → (lub po prostu użyj bezpośrednio nazw właściwości)
  • [IgnoreDataMember][JsonIgnore]
  • [DataContract] → Żaden odpowiednik nie jest potrzebny (System.Text.Json domyślnie serializuje właściwości publiczne)

API, które się nie zmienia

Windows.Devices.*, Windows.Media.*, Windows.UI.ViewManagement.UISettings, Windows.UI.Color, a większość interfejsów API WinRT poza przestrzenią nazw XAML pozostaje niezmieniona.

Kontrolki bez bezpośredniego odpowiednika

Niektóre kontrolki platformy UWP nie istnieją w systemie WinUI 3. Wybierz zamianę w zależności od scenariusza:

Kontrolka UWP Zamiennik WinUI 3 Notatki
Pivot TabView, NavigationView (tryb górny) lub RadioButtons + widoczność W przypadku 2–3 stałych kart najprostszym rozwiązaniem jest RadioButtons z przełączaniem widoczności. W przypadku kart dynamicznych/zamykanych użyj polecenia TabView.
InkToolbar (niestandardowa podklasa) CommandBar z AppBarToggleButton elementami Wbudowane InkToolbar istnieją, ale niestandardowe wzorce dziedziczenia nie dają się łatwo przełożyć. Przebuduj niestandardowe paski narzędzi za pomocą CommandBar.
RadialController Współdziałanie WinRT z uchwytem okna RadialController.CreateForCurrentView() nie ma bezpośredniego odpowiednika. Użyj RadialControllerInterop z GetForWindow(hwnd).
SystemNavigationManager Niestandardowy przycisk Wstecz lub NavigationView.IsBackEnabled SystemNavigationManager.GetForCurrentView() nie istnieje. Dodaj własny przycisk Wstecz lub użyj NavigationViewwbudowanego przycisku Wstecz.

Ink, Win2D i drukowanie

Te podsystemy wymagają określonych kroków migracji poza zmianami przestrzeni nazw.

Windows Ink

Interfejsy API InkCanvas i InkPresenter zostają przeniesione do Microsoft.UI.Input.Inking, ale poza tym pozostają identyczne. Ta nieoczywista zmiana to CoreInputDeviceTypes:

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

InkStrokeContainer.SaveAsync() i LoadAsync() nadal wymagają IRandomAccessStream. Mostek ze System.IO strumieni:

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

Nazwa pakietu Win2D została zmieniona, ale powierzchnia interfejsu API jest identyczna:

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

Wszystkie Microsoft.Graphics.Canvas.* interfejsy API (CanvasDevice, CanvasBitmap, CanvasRenderTarget, DrawInk) działają w taki sam sposób. Tylko odwołanie do pakietu NuGet wymaga aktualizacji.

Drukowanie

Drukowanie platformy UWP używa funkcji PrintManager.GetForCurrentView(). WinUI 3 wymaga współdziałania z uchwytem okna:

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

Interfejsy API renderowania PrintDocument (Paginate, GetPreviewPage, AddPages) pozostają bez zmian.

Important

Jeśli pominięto uchwyt okna, PrintManagerInterop.GetForWindow zwraca wartość COMException. Jest to ten sam wzorzec interoperacyjności co FileOpenPicker — każdy interfejs API, który używał GetForCurrentView() w środowisku UWP, wymaga uchwytu okna w WinUI 3.

Monit startowy

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.

Zmiany w plikach projektu

Zastąp platformę docelową UWP:

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

Dodaj pakiet Zestaw SDK do aplikacji systemu Windows:

dotnet add package Microsoft.WindowsAppSDK