Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
UWP ya no está en desarrollo activo. WinUI 3 y el SDK de Aplicaciones para Windows son sus sucesores, y las herramientas de inteligencia artificial pueden automatizar la mayor parte de la migración. El principal desafío es que los modelos de inteligencia artificial se entrenaron en años de ejemplos de UWP, por lo que sin instrucciones reproducen los patrones de los que intentas alejarte. Esta página proporciona a tu agente el contexto que necesita para hacerlo bien.
Instalación del complemento del agente de WinUI
La winui-uwp-migration función gestiona automáticamente las sustituciones comunes:
gh copilot plugin install winui@awesome-copilot
Consulte el complemento del agente de WinUI para obtener todos los detalles.
Tabla de sustitución de API
En las tablas siguientes se resumen las sustituciones de API más comunes. Para obtener la asignación detallada completa (incluidos los miembros, las propiedades y las API menos comunes), consulta Asignación de API y bibliotecas de UWP a la SDK de Aplicaciones para Windows.
Importante
x:Bind está en modo OneTime de forma predeterminada. A diferencia {Binding} de (que tiene OneWaycomo valor predeterminado ), x:Bind solo se evalúa una vez a menos que especifique Mode=OneWay o Mode=TwoWay. Durante la migración, audite todas las expresiones x:Bind que están vinculadas a propiedades que cambian durante la ejecución; la ausencia de Mode=OneWay provoca errores de "la interfaz de usuario no se actualiza" que son indetectables en tiempo de compilación.
Espacios de nombres
| 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 (de un Window o Page) |
Windowing
| UWP | WinUI 3 |
|---|---|
ApplicationView |
AppWindow |
ApplicationView.GetForCurrentView() |
AppWindow.GetFromWindowId(...) |
ApplicationViewTitleBar |
AppWindowTitleBar |
CoreWindow |
Microsoft.UI.Xaml.Window |
SystemNavigationManager |
Botón de retroceso mediante AppWindowTitleBar |
Cuadros de diálogo y selectores
| UWP | WinUI 3 |
|---|---|
MessageDialog |
ContentDialog (establecer XamlRoot) |
FileOpenPicker |
FileOpenPicker + InitializeWithWindow |
FileSavePicker |
FileSavePicker + InitializeWithWindow |
FolderPicker |
FolderPicker + InitializeWithWindow |
Importante
Los selectores requieren InitializeWithWindow antes de llamar a PickSingleFileAsync (o algo similar):
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(App.MainWindow);
WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd);
ContentDialog requiere XamlRoot (no InitializeWithWindow):
var dialog = new ContentDialog { XamlRoot = this.Content.XamlRoot, ... };
await dialog.ShowAsync();
Notificaciones
| UWP | WinUI 3 |
|---|---|
Windows.UI.Notifications.ToastNotificationManager |
Microsoft.Windows.AppNotifications.AppNotificationManager |
Windows.UI.Notifications.BadgeUpdateManager |
Microsoft.Windows.BadgeNotifications.BadgeNotificationManager |
Windows.UI.Notifications.TileUpdateManager |
Los iconos están en desuso: usar notificaciones o widgets |
Redes y HTTP
| UWP | WinUI 3 (recomendado) |
|---|---|
Windows.Web.Http.HttpClient |
System.Net.Http.HttpClient (portable, sin dependencia de WinRT) |
Windows.Web.Syndication.SyndicationClient |
System.ServiceModel.Syndication.SyndicationFeed + HttpClient |
Windows.Web.AtomPub.AtomPubClient |
System.ServiceModel.Syndication o HTTP directa |
Note
Las API HTTP de WinRT (Windows.Web.Http) siguen funcionando en aplicaciones WinUI 3 empaquetadas, pero se recomiendan los equivalentes de .NET por motivos de portabilidad, una depuración más sencilla y una compatibilidad más amplia con el ecosistema (middleware, inyección de dependencias, simulación).
Navegación
| UWP | WinUI 3 |
|---|---|
Frame.Navigate(typeof(MyPage)) |
Frame.Navigate(typeof(MyPage)) — sin cambios |
SystemNavigationManager.BackRequested |
Gestionar mediante NavigationView o AppWindow |
Windows.UI.Core.Preview.SystemNavigationManagerPreview |
AppWindow.Closing evento |
Note
Navegación tipo hamburguesa personalizada (SplitView + NavMenuListView): Muchos ejemplos de UWP implementaban la navegación mediante un AppShell.xaml personalizado con SplitView y un control NavMenuListView creado a mano (más de 500 líneas). En WinUI 3, reemplace todo este patrón por NavigationView, que proporciona la misma experiencia de usuario con accesibilidad integrada, comportamiento dinámico y compatibilidad con botón atrás. Normalmente, se trata de una reducción de código de 80%.
Patrones de MVVM
| UWP (implementaciones personalizadas comunes) | WinUI 3 (recomendado) |
|---|---|
Personalizado BindableBase / ObservableObject |
CommunityToolkit.Mvvm.ComponentModel.ObservableObject |
Personalizado DelegateCommand / RelayCommand |
CommunityToolkit.Mvvm.Input.RelayCommand |
Manual SetProperty + OnPropertyChanged |
[ObservableProperty] generador de código fuente |
INavigationService personalizado |
Integrado Frame.Navigate + NavigationView |
Sugerencia
El paquete NuGet CommunityToolkit.Mvvm es la base de MVVM recomendada para aplicaciones winUI 3. Reemplaza las clases base hechas manualmente por equivalentes probados generados a partir del código fuente, eliminando cientos de líneas de código repetitivo.
dotnet add package CommunityToolkit.Mvvm
Ciclo de vida de la aplicación
| UWP | WinUI 3 |
|---|---|
Application.Current.Suspending |
Microsoft.Windows.AppLifecycle (requiere cambios arquitectónicos; consulte la nota) |
Application.Current.Resuming |
AppInstance.GetCurrent().Activated (consulte la nota) |
BackgroundTaskBuilder |
Tareas en segundo plano del SDK de aplicaciones de Windows |
Note
La migración del ciclo de vida de aplicaciones de WinUI 3 no es un intercambio simple de nombres de API. El SDK de Aplicaciones para Windows usa un modelo de activación y suspensión diferente. Trate el código del ciclo de vida como algo que requiere una reescritura específica en lugar de una sustitución automatizada. Consulte la documentación del ciclo de vida de SDK de Aplicaciones para Windows para ver el modelo completo.
Configuración y almacenamiento
| UWP | WinUI 3 (empaquetado) | WinUI 3 (sin empaquetar) |
|---|---|---|
ApplicationData.Current.LocalSettings |
Sin cambios | ❌ Lanza una excepción: falta identidad del paquete |
ApplicationData.Current.LocalFolder |
Sin cambios | ❌ Lanza una excepción: falta identidad del paquete |
Windows.Storage.KnownFolders |
Sin cambios | ❌ Lanza una excepción: falta identidad del paquete |
Warning
Las aplicaciones desempaquetadas no pueden usar ApplicationData.Current: genera un error en tiempo de ejecución porque no existe identidad de paquete. En su lugar, use las API de archivo .NET estándar:
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
Si tu aplicación para UWP usaba DataContractSerializer con [DataMember]/[IgnoreDataMember], considera migrar a System.Text.Json (más rápido, más pequeño y compatible con la generación de código fuente). La asignación de atributos es:
-
[DataMember]→[JsonPropertyName("name")](o simplemente usar los nombres de las propiedades directamente) -
[IgnoreDataMember]→[JsonIgnore] -
[DataContract]→ No se necesita ningún equivalente (System.Text.Json serializa las propiedades públicas de forma predeterminada)
API que no cambian
Windows.Devices.*, Windows.Media.*, Windows.UI.ViewManagement.UISettings, Windows.UI.Color y la mayoría de las API de WinRT fuera del espacio de nombres XAML no cambian.
Controles sin un equivalente directo
Algunos controles de UWP no existen en WinUI 3. Elija un reemplazo en función de su escenario:
| Control de UWP | Reemplazo de WinUI 3 | Notas |
|---|---|---|
Pivot |
TabView, NavigationView (modo superior) o RadioButtons + visibilidad |
Para 2 o 3 pestañas fijas, RadioButtons con alternancia de visibilidad es lo más sencillo. Para las pestañas dinámicas o que se pueden cerrar, use TabView. |
InkToolbar (subclase personalizada) |
CommandBar con AppBarToggleButton elementos |
El elemento integrado InkToolbar existe, pero los patrones de subclases personalizados no se traducen de forma limpia. Recompile las barras de herramientas personalizadas mediante CommandBar. |
RadialController |
Interoperabilidad de WinRT con identificador de ventana |
RadialController.CreateForCurrentView() no tiene equivalente directo. Usar RadialControllerInterop con GetForWindow(hwnd). |
SystemNavigationManager |
Botón de retroceso personalizado o NavigationView.IsBackEnabled |
SystemNavigationManager.GetForCurrentView() no existe. Añada su propio botón de retroceso o use el botón de retroceso integrado de NavigationView. |
Ink, Win2D e impresión
Estos subsistemas requieren pasos de migración específicos más allá de los cambios en el espacio de nombres.
Windows Ink
Las InkCanvas API y InkPresenter se trasladan a Microsoft.UI.Input.Inking, pero por lo demás son idénticas. El cambio no obvio es CoreInputDeviceTypes:
| UWP | WinUI 3 |
|---|---|
Windows.UI.Input.Inking.* |
Microsoft.UI.Input.Inking.* |
Windows.UI.Core.CoreInputDeviceTypes |
Microsoft.UI.Core.CoreInputDeviceTypes |
InkStrokeContainer.SaveAsync() y LoadAsync() todavía requieren IRandomAccessStream. Puente desde flujos System.IO:
// 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
El nombre del paquete Win2D cambió, pero la superficie de API es idéntica:
| UWP | WinUI 3 |
|---|---|
Win2D.uwp (NuGet) |
Microsoft.Graphics.Win2D (NuGet) |
Todas las Microsoft.Graphics.Canvas.* API (CanvasDevice, CanvasBitmap, CanvasRenderTarget, DrawInk) funcionan de la misma manera. Solo la referencia del paquete NuGet necesita actualizarse.
Impresión
La impresión de UWP utiliza PrintManager.GetForCurrentView(). WinUI 3 requiere interoperabilidad con el identificador de ventana:
// 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);
Las PrintDocument API de representación (Paginate, GetPreviewPage, AddPages) no se modifican.
Importante
Si omites el identificador de ventana, PrintManagerInterop.GetForWindow lanza un COMException. Este es el mismo patrón de interoperabilidad que FileOpenPicker: cualquier API que usaba GetForCurrentView() en UWP necesita un identificador de ventana en WinUI 3.
Mensaje de inicio
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.
Cambios en el archivo del proyecto
Reemplazar el marco de destino de 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>
Agregue el paquete SDK de Aplicaciones para Windows:
dotnet add package Microsoft.WindowsAppSDK
Contenido relacionado
- guía de migración de SDK de Aplicaciones para Windows: tutorial completo de migración manual
- Asignación de API y bibliotecas para UWP a la SDK de Aplicaciones para Windows: tabla completa de asignación de API
- Lo que se admite al migrar de UWP a WinUI : estado de compatibilidad de características
- Migrar desde WPF