在.NET MAUI中调用PopAsync触发异常的原因排查
MAUI Shell导航中PopAsync触发异常问题
我在使用MAUI Shell导航框架时,从ProfessionalPage的ViewModel通过GoToAsync跳转到AddReviewPage,完成数据持久化后调用PopAsync返回时触发异常,但导航栈不为空。直接跳转到Shell根目录的GoToAsync("//Main")可以正常运行,但不符合预期。
从ProfessionalPage跳转到AddReviewPage的代码
private async void OnAddReviewClicked() { var parameters = new Dictionary<string, object> { { "ProfessionalId", ProfessionalId } }; await Shell.Current.GoToAsync(nameof(AddReviewPage), parameters); }
AddReviewViewModel中尝试返回的代码
private async void OnAddReviewClicked() { // 持久化代码 if (success == true) { await App.Current.MainPage.DisplayAlert("Sucess!", "Success!", "OK"); // 此处触发异常 await Shell.Current.Navigation.PopAsync(); // 但导航到Shell根目录的代码可正常运行,不符合预期 //await Shell.Current.GoToAsync("//Main"); } }
Shell的XAML注册配置
<Shell x:Class="MyApp.Presentation.Mobile.AppShell" xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MyApp.Presentation.Mobile" xmlns:views="clr-namespace:MyApp.Presentation.Mobile.Views" Shell.FlyoutBehavior="Disabled"> <ShellContent Title="LogIn" ContentTemplate="{DataTemplate views:LogInPage}" Route="LogInPage" /> <TabBar Route="Main"> <!-- 主标签页 --> </TabBar> <ShellContent Title="Professional" ContentTemplate="{DataTemplate views:ProfessionalPage}" Route="ProfessionalPage" /> <ShellContent Title="AddReview" ContentTemplate="{DataTemplate views:AddReviewPage}" Route="AddReviewPage" />
代码后台的路由注册
public partial class AppShell : Shell { public AppShell() { InitializeComponent(); Routing.RegisterRoute(nameof(LogInPage), typeof(LogInPage)); Routing.RegisterRoute(nameof(ProfessionalPage), typeof(ProfessionalPage)); Routing.RegisterRoute(nameof(AddReviewPage), typeof(AddReviewPage)); } }
问题原因及解决方案
核心原因
你的路由配置存在层级错误:将ProfessionalPage和AddReviewPage设为同级的Shell根级页面。此时用GoToAsync跳转时,是替换Shell的当前根页面,而非将AddReviewPage压入ProfessionalPage的导航栈,导致导航栈中仅存在AddReviewPage,调用PopAsync自然触发异常。
解决方案
方案1:调整路由层级,注册子路由
- 删除XAML中单独的
AddReviewPage的ShellContent节点 - 修改后台路由注册,将AddReviewPage设为ProfessionalPage的子路由:
public partial class AppShell : Shell { public AppShell() { InitializeComponent(); Routing.RegisterRoute(nameof(LogInPage), typeof(LogInPage)); Routing.RegisterRoute(nameof(ProfessionalPage), typeof(ProfessionalPage)); // 注册子路由,关联到ProfessionalPage Routing.RegisterRoute($"{nameof(ProfessionalPage)}/{nameof(AddReviewPage)}", typeof(AddReviewPage)); } }
- 跳转代码保持不变,此时
GoToAsync会自动将AddReviewPage压入ProfessionalPage的导航栈,PopAsync即可正常返回。
方案2:使用Shell推荐的返回语法
无需修改路由配置,将PopAsync替换为Shell导航的相对路径返回:
await Shell.Current.GoToAsync("..");
这种方式更适配Shell的路由系统,无需依赖传统导航栈的操作逻辑。
内容的提问来源于stack exchange,提问作者adamasan
相关产品推荐
相关产品推荐

