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

WinUI 3.0 Desktop C# 如何导航到已存在Page实例并保留页面状态

我正在使用微软推出的新一代UI技术WinUI 3进行桌面开发。
我的问题与Stack Overflow上的「WinUI 3.0 Desktop - C# Page Navigation」提问类似,但我具体想要了解如何导航到已存在的Page实例,而非每次跳转都创建新实例。

我应用的主菜单使用NavigationView控件实现。
备注:我安装了xaml-controls-gallery示例解决方案来学习WinUI 3的基础概念。

目前我在NavigationView中添加了3个NavigationViewItem实例,XAML代码如下:

<NavigationView x:Name="navigationView" PaneDisplayMode="Top" 
                SelectionFollowsFocus="Enabled" IsBackButtonVisible="Collapsed" ItemInvoked="NavigationView_OnItemInvoked"
>
    <NavigationView.MenuItems>
        <NavigationViewItem Icon="Play" Content="Menu 1" x:Name="Menu1Item" Tag="Page1" />
        <NavigationViewItem Icon="Filter" Content="Menu 2" x:Name="Menu2Item" Tag="Page2"/>
        <NavigationViewItem Icon="Refresh" Content="Menu 3" x:Name="Menu3Item" Tag="Page3" />
    </NavigationView.MenuItems>

    <!-- 选中导航项对应的内容会展示在这个区域 -->
    <Grid Padding="20">
        <Frame x:Name="rootFrame" Navigated="RootFrame_OnNavigated"/>
    </Grid>
</NavigationView>

每个菜单项对应的内容需要展示在名为rootFrame的Frame控件中,我已经为内容创建了三个Page类:Page1、Page2、Page3。
在后置代码中,我处理了NavigationView的ItemInvoked事件,通过判断被点击导航项的Tag获取对应Page类型,再调用导航方法,代码如下:

private void NavigationView_OnItemInvoked(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs args)
{
    FrameNavigationOptions navOptions = new FrameNavigationOptions();
    navOptions.TransitionInfoOverride = args.RecommendedNavigationTransitionInfo;

    string navItemTag = args.InvokedItemContainer.Tag.ToString();

    Type pageType = null;
    if (navItemTag == "Page1")
    {
        pageType = typeof(Page1);
    }
    else if (navItemTag == "Page2")
    {
        pageType = typeof(Page2);
    }
    else if (navItemTag == "Page3")
    {
        pageType = typeof(Page3);
    }

    if (pageType == null)
    {
        return;
    }

    rootFrame.NavigateToType(pageType, null, navOptions);
}

但问题在于,对Frame实例调用NavigateToType每次都会创建新的Page类实例,会丢失用户修改过的页面状态,还会重复执行耗时的数据加载操作。我希望可以导航到已经存在的Page实例,保留原有状态。
目前我还没有找到实现方案,由此带来的现象是:在Page的OnNavigatedTo事件中,参数e的NavigationMode属性始终为NavigationMode.New,而不是我期望的NavigationMode.Refresh,以Page1为例:

public sealed partial class Page1 : Page
{
    public Page1()
    {
        this.InitializeComponent();
        
        ViewModel = new Page1ViewModel();
        // 加载数据(耗时操作)
    }

    public Page1ViewModel ViewModel { get; set; }


    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        // e.NavigationMode始终为NavigationMode.New 
        // 如何才能得到NavigationMode.Refresh?
    }
}

请问有人知道如何实现导航到已存在的Page实例吗?
我尝试过的 workaround 是直接替换Frame的Content:

rootFrame.Content = instanceOfPage;

但我不想使用这个方案,因为它绕过了Frame的原生导航逻辑,也无法触发跳转时的过渡动画。
我了解到WPF和旧版.NET Framework中有NavigationWindow类可以实现该需求,但WinUI中暂时还没有这个类,请问WinUI 3中有没有正规的实现方案?

内容的提问来源于stack exchange,提问作者Martin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 15:00:07