如何在Xamarin中导航至已打开的页面实例?
在Xamarin Shell中导航至已打开的页面实例
针对你遇到的从菜单打开页面复用实例,但通过Shell.Current.GoToAsync("//MyOrdersPage")导航时新建实例的问题,可以用以下两种方法解决:
方法一:手动检查并激活已存在的页面实例
遍历当前导航栈,找到目标页面的实例后,将其设为当前活动页面,并清理它之后的页面:
// 查找导航栈中是否存在MyOrdersPage实例 var targetPage = Shell.Current.Navigation.NavigationStack.FirstOrDefault(page => page is MyOrdersPage); if (targetPage != null) { // 移除目标页面之后的所有页面,避免栈冗余 while (Shell.Current.Navigation.NavigationStack.Last() != targetPage) { Shell.Current.Navigation.RemovePage(Shell.Current.Navigation.NavigationStack.Last()); } // 无动画地回到目标页面,激活已存在的实例 await Shell.Current.Navigation.PopToAsync(targetPage, animate: false); } else { // 实例不存在时,再导航到新页面 await Shell.Current.GoToAsync("//MyOrdersPage"); }
方法二:配置路由为单实例模式
在注册路由时,指定页面为SingleInstance模式,这样无论通过哪种方式导航,都会复用同一个页面实例:
代码注册方式(在AppShell.xaml.cs中)
public AppShell() { InitializeComponent(); // 注册路由并设置为单实例 Routing.RegisterRoute(nameof(MyOrdersPage), typeof(MyOrdersPage), new ShellNavigationState("//MyOrdersPage") { RouteType = RouteType.SingleInstance }); }
XAML配置方式
直接在AppShell.xaml的ShellContent节点中添加RouteType属性:
<FlyoutItem Title="我的订单"> <ShellContent Route="MyOrdersPage" ContentTemplate="{DataTemplate local:MyOrdersPage}" RouteType="SingleInstance" /> </FlyoutItem>
注意事项
- 使用
SingleInstance模式后,页面的OnAppearing会在每次激活时触发,OnDisappearing仅在页面被销毁时触发,需要注意页面状态的保存与恢复逻辑。 - 菜单中的FlyoutItem默认就是复用实例的,配置单实例后可以让代码导航的行为与菜单保持一致。
内容的提问来源于stack exchange,提问作者anand
相关产品推荐
相关产品推荐

