WinUI 3.0 桌面 - C# 页面导航到现有页面实例
WinUI 3.0 Desktop - C# Page Navigation to existing page instances
我已经开始使用 WinUI 3,这是 Microsoft 的新 UI 技术。
我的问题与这个问题类似 ,但我特别想了解如何导航到现有页面实例。
我的应用程序的主菜单包含一个 NavigationView 控件。
备注:我安装了 this 示例解决方案(“xaml-controls-gallery”)以了解其基本概念。
目前我里面有3个NavigationViewItem实例:
<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>
<!-- The section will contain the content for selected navigation item -->
<Grid Padding="20">
<Frame x:Name="rootFrame" Navigated="RootFrame_OnNavigated"/>
</Grid>
</NavigationView>
属于相应菜单项的内容应显示在框架“rootFrame”中。对于我创建的第 class 页的内容:第 1 页、第 2 页和第 3 页。
在代码隐藏文件中,我处理了 NavigationView 的“ItemInvoked”事件。我检查了 NavigationItem 的“标签”并设置了我要导航到的页面的类型。
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”总是会创建页面的新实例 class。我想要的是不要丢失用户也对 UI 进行了一些更改的页面状态。所以我想导航到页面的现有实例。
我不知道如何完成这个。
因此,在页面的“OnNavigatedTo”事件中,“e”参数的 NavigationMode 始终是 NavigationMode.New 而不是 NavigationMode.Refresh。这是“Page1”的示例:
public sealed partial class Page1 : Page
{
public Page1()
{
this.InitializeComponent();
ViewModel = new Page1ViewModel();
// Load data (expensive operation)
}
public Page1ViewModel ViewModel { get; set; }
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// e.NavigationMode is always NavigationMode.New
// How do we get NavigationMode.Refresh?
}
}
有人知道如何导航到现有页面实例吗?
作为解决方法,我尝试直接交换框架的内容:
rootFrame.Content = instanceOfPage;
但我真的不想这样做,因为这会绕过基于框架的导航,并且在导航到其他页面时也不会显示动画。
似乎在 WPF 和“旧的”.NET 框架中有一个 class NavigationWindow 可以达到这个目的,但这在 WinUi 中还不存在。
将页面的 NavigationCacheMode 属性 设置为 Required
或 Enabled
:
<Page
x:Class="WinUI3App.Page1"
NavigationCacheMode="Enabled"
...
另请参阅这篇文章:Implement navigation between two pages - 4. Cache a page
我已经开始使用 WinUI 3,这是 Microsoft 的新 UI 技术。
我的问题与这个问题类似
我的应用程序的主菜单包含一个 NavigationView 控件。
备注:我安装了 this 示例解决方案(“xaml-controls-gallery”)以了解其基本概念。
目前我里面有3个NavigationViewItem实例:
<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>
<!-- The section will contain the content for selected navigation item -->
<Grid Padding="20">
<Frame x:Name="rootFrame" Navigated="RootFrame_OnNavigated"/>
</Grid>
</NavigationView>
属于相应菜单项的内容应显示在框架“rootFrame”中。对于我创建的第 class 页的内容:第 1 页、第 2 页和第 3 页。
在代码隐藏文件中,我处理了 NavigationView 的“ItemInvoked”事件。我检查了 NavigationItem 的“标签”并设置了我要导航到的页面的类型。
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”总是会创建页面的新实例 class。我想要的是不要丢失用户也对 UI 进行了一些更改的页面状态。所以我想导航到页面的现有实例。
我不知道如何完成这个。
因此,在页面的“OnNavigatedTo”事件中,“e”参数的 NavigationMode 始终是 NavigationMode.New 而不是 NavigationMode.Refresh。这是“Page1”的示例:
public sealed partial class Page1 : Page
{
public Page1()
{
this.InitializeComponent();
ViewModel = new Page1ViewModel();
// Load data (expensive operation)
}
public Page1ViewModel ViewModel { get; set; }
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// e.NavigationMode is always NavigationMode.New
// How do we get NavigationMode.Refresh?
}
}
有人知道如何导航到现有页面实例吗?
作为解决方法,我尝试直接交换框架的内容:
rootFrame.Content = instanceOfPage;
但我真的不想这样做,因为这会绕过基于框架的导航,并且在导航到其他页面时也不会显示动画。
似乎在 WPF 和“旧的”.NET 框架中有一个 class NavigationWindow 可以达到这个目的,但这在 WinUi 中还不存在。
将页面的 NavigationCacheMode 属性 设置为 Required
或 Enabled
:
<Page
x:Class="WinUI3App.Page1"
NavigationCacheMode="Enabled"
...
另请参阅这篇文章:Implement navigation between two pages - 4. Cache a page