You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将给定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/扩展方法EnqueueAsync
  • ApplicationView.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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 19:57:15