如何将给定UWP多视图代码转换为Windows App SDK等效实现?
UWP 独立新视图创建代码迁移至 Windows App SDK 方案
UWP 中基于CoreApplication视图模型的多窗口逻辑,在Windows App SDK(WinUI 3)中已经替换为原生多Window模型,没有直接一一对应的CoreApplication、ApplicationViewSwitcher类型,等效实现逻辑如下:
核心API对应关系
CoreApplication.CreateNewView():直接实例化新的Window对象,每个Window自带独立的UI线程调度器CoreDispatcher.RunAsync:替换为WinUI 3的DispatcherQueue.TryEnqueue/扩展方法EnqueueAsyncApplicationView.GetForCurrentView().Id:可自行维护自增视图ID,或直接使用Windows App SDK 1.4+提供的系统级AppWindow.Id作为唯一标识ApplicationViewSwitcher.TryShowAsStandaloneAsync:无需调用该类API,新Window实例调用Activate()后会直接作为独立顶层窗口显示
等效实现代码
注意:必须对新建的Window持有强引用,否则会被垃圾回收导致窗口闪退,建议在App类中维护全局活动窗口列表
using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using System.Collections.Generic; using System.Threading.Tasks; // 放在App.xaml.cs中即可,全局维护活动窗口引用 public partial class App : Application { // 持有所有打开窗口的强引用,避免GC回收 public static List<Window> ActiveWindows { get; } = new List<Window>(); internal static int _nextCustomViewId = 1; } public async Task<int> CreateNewViewAsync(Type viewModelType, object parameter = null) { int viewId = 0; Window newWindow = new Window(); App.ActiveWindows.Add(newWindow); // 在新窗口的UI线程执行初始化逻辑 await newWindow.DispatcherQueue.EnqueueAsync(DispatcherQueuePriority.Normal, () => { // 分配视图ID,高版本WinAppSDK可直接替换为 viewId = newWindow.AppWindow.Id.Value; viewId = App._nextCustomViewId++; Frame frame = new Frame(); ShellArgs args = new ShellArgs { ViewModel = viewModelType, Parameter = parameter }; frame.Navigate(typeof(ShellView), args); newWindow.Content = frame; // 窗口关闭时自动从引用列表移除,避免内存泄漏 newWindow.Closed += (sender, _) => { if (sender is Window closedWin) { App.ActiveWindows.Remove(closedWin); } }; newWindow.Activate(); }); return viewId != 0 ? viewId : 0; }
补充说明
- 若项目未引入
DispatcherQueue.EnqueueAsync扩展方法,可手动通过TaskCompletionSource结合TryEnqueue实现异步等待逻辑 - 如需实现原UWP中窗口切换、指定大小显示、置顶等交互,可通过
newWindow.AppWindow暴露的相关API实现,包括调整窗口尺寸、设置窗口显示模式、调整Z序等 - 导航逻辑、ShellView/ShellArgs等业务自定义类型和原UWP写法完全一致,无需额外修改
内容的提问来源于stack exchange,提问作者Fabio Massicci
相关产品推荐
相关产品推荐

