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. |
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
WinUI incluye InkCanvas, InkToolbary InkPresenter como API experimentales en versiones experimentales del SDK de Aplicaciones para Windows. Las versiones estables no las incluyen. Para obtener información sobre la configuración, la personalización de la barra de herramientas y las limitaciones conocidas, consulte Controles de entrada manuscrita para aplicaciones WinUI.
En versiones experimentales, los controles y los tipos que procesan la entrada manuscrita están en Microsoft.UI.Xaml.Controls. Los trazos y los atributos de dibujo permanecen en Windows.UI.Input.Inking:
| UWP | WinUI 3 (versiones experimentales) |
|---|---|
Windows.UI.Xaml.Controls.InkCanvas, InkToolbary los otros InkToolbar* tipos |
Microsoft.UI.Xaml.Controls, los mismos nombres de tipo. Algunos miembros difieren. |
Windows.UI.Input.Inking.InkPresenter, InkStrokeContainer, InkStrokeInput, InkUnprocessedInput, InkSynchronizer, InkInputConfiguration, InkInputProcessingConfiguration, InkInputProcessingMode, InkInputRightDragAction, InkHighContrastAdjustment, InkStrokesCollectedEventArgs, InkStrokesErasedEventArgs |
Microsoft.UI.Xaml.Controls, los mismos nombres de tipo. Algunos miembros difieren. |
Windows.UI.Input.Inking.InkStroke, InkDrawingAttributes, InkPoint, InkStrokeBuilder, InkPersistenceFormat, PenTipShape |
Sin cambios |
Windows.UI.Core.CoreInputDeviceTypes |
Sin cambios |
Cada tipo de UWP de las dos primeras filas tiene un homólogo con el mismo nombre, pero SDK de Aplicaciones para Windows 2.5.4-experimental no incluye todos sus miembros:
-
InkStrokeContainerno tiene ningún constructor público yInkPresenter.StrokeContaineres de solo lectura. Para cambiar entre conjuntos de trazos, guarde cada conjunto conSaveAsyncy restáurelo conLoadAsync, que reemplaza los trazos actuales. -
SaveAsyncyLoadAsyncdevuelvenIAsyncAction, por lo que no notifican el progreso ySaveAsyncno devuelve el número de bytes que escribió. -
InkStrokeContainer.GetRecognitionResults,InkStrokeContainer.UpdateRecognitionResultsyInkInputConfiguration.IsPenHapticFeedbackEnabledno están disponibles. -
InkToolbarRulerButton.Rulery elInkToolbar.IsRulerButtonCheckedChangedevento no están disponibles. UWP dejó de usarInkToolbarRulerButtonen favor deInkToolbarStencilButton, así que use el botón de plantilla y el eventoInkToolbar.IsStencilButtonCheckedChangeden su lugar.
SDK de Aplicaciones para Windows 2.4.1-experimental agregó API de borrado, como InkToolbarEraserKind y InkToolbarEraserButton.SelectedEraser, que 2.5.4-experimental eliminó. Nunca formaron parte de UWP, por lo que no los agregues al código migrado. Para obtener la lista completa, consulte Cambios de la versión 2.4.1-experimental.
Dado que los tipos como InkPresenter y InkStrokeContainer existen en ambos espacios de nombres, importar ambos Microsoft.UI.Xaml.Controls y Windows.UI.Input.Inking provoca el error CS0104 cuando se usan esos nombres. Importe Microsoft.UI.Xaml.Controlsy agregue directivas de alias para los Windows.UI.Input.Inking tipos que use:
using Microsoft.UI.Xaml.Controls;
using InkDrawingAttributes = Windows.UI.Input.Inking.InkDrawingAttributes;
using InkStroke = Windows.UI.Input.Inking.InkStroke;
InkStrokeContainer.SaveAsync escribe en un IOutputStream, y LoadAsync lee de un IInputStream. Para usar System.IO flujos de archivo, conviértelos con AsOutputStream y AsInputStream. El archivo necesita using System; para esperar estos métodos de Windows Runtime, junto con using System.IO; y 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);
}
Puede seguir conectando la barra de herramientas al lienzo con InkToolbar.TargetInkCanvas, o establecer TargetInkPresenter para conectarla directamente a un InkPresenter. Para agregar sus propias herramientas a la barra de herramientas, use InkToolbarCustomToolButton y InkToolbarCustomToggleButton, como se muestra en Personalizar la barra de herramientas de entrada de lápiz. Antes de migrar, revise las limitaciones conocidas, como los problemas notificados con la regla y las plantillas de transportador.
Si la aplicación debe usar una versión estable, no hay ningún control de entrada manuscrita integrado al que migrar. Representar trazos con Win2D y controlar la entrada de puntero usted mismo, o usar una biblioteca de entrada manuscrita de terceros. Para reemplazar InkToolbar, use un CommandBar con AppBarToggleButton elementos.
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)
- 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.
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