如何让MAUI在Shell导航返回后再执行后续代码?
解决Shell导航后等待返回再执行代码的问题
Shell的Shell.Current.GoToAsync("ContentPage")调用的await只会等待导航到目标页面完成(即ContentPage显示出来),并不会自动等待你从ContentPage返回。要实现等待返回后再执行后续代码,可以用TaskCompletionSource手动创建等待信号,或者通过事件解耦实现,以下是具体方案:
方案1:直接用TaskCompletionSource实现页面间等待
步骤1:在MainPage中定义等待信号
在MainPage类里添加一个TaskCompletionSource<bool>字段,用来标记是否已从ContentPage返回:
private TaskCompletionSource<bool> _returnWaiter; private async void NavigateToContentButton_Clicked(object sender, EventArgs e) { // 初始化等待信号 _returnWaiter = new TaskCompletionSource<bool>(); // 导航到ContentPage,此处await仅等待页面跳转完成 await Shell.Current.GoToAsync("ContentPage"); // 等待ContentPage返回的信号 await _returnWaiter.Task; // 以下代码会在返回MainPage后才执行 var sessionData = Utilities.GetCurrentSessionData(); // 其他后续逻辑... }
步骤2:在ContentPage返回时触发信号
在ContentPage的返回逻辑(比如自定义返回按钮点击事件)中,回到MainPage后触发等待信号:
private async void BackToMainButton_Clicked(object sender, EventArgs e) { // 导航回MainPage await Shell.Current.GoToAsync(".."); // 获取MainPage实例并触发等待完成 if (Shell.Current.CurrentPage is MainPage mainPage && mainPage._returnWaiter != null) { mainPage._returnWaiter.SetResult(true); // 清理信号,避免重复触发 mainPage._returnWaiter = null; } }
补充:处理系统返回键的情况
如果用户可能通过系统返回键(而非自定义按钮)返回,需要在ContentPage的OnDisappearing方法中触发信号:
protected override void OnDisappearing() { base.OnDisappearing(); // 确认是返回上一页(避免页面被其他页面覆盖的情况) if (Shell.Current.Navigation.NavigationStack.LastOrDefault() != this) { if (Shell.Current.CurrentPage is MainPage mainPage && mainPage._returnWaiter != null) { mainPage._returnWaiter.SetResult(true); mainPage._returnWaiter = null; } } }
方案2:用事件解耦页面依赖
如果不想让ContentPage直接依赖MainPage实例,可以用静态事件传递返回信号,实现松耦合:
步骤1:在ContentPage定义返回事件
public static event Action OnReturned; private async void BackToMainButton_Clicked(object sender, EventArgs e) { await Shell.Current.GoToAsync(".."); // 触发返回事件 OnReturned?.Invoke(); }
步骤2:在MainPage订阅事件并等待
private async void NavigateToContentButton_Clicked(object sender, EventArgs e) { var tcs = new TaskCompletionSource<bool>(); Action returnHandler = () => tcs.SetResult(true); // 订阅返回事件 ContentPage.OnReturned += returnHandler; try { await Shell.Current.GoToAsync("ContentPage"); // 等待返回事件触发 await tcs.Task; // 返回后执行的代码 var sessionData = Utilities.GetCurrentSessionData(); } finally { // 取消订阅,避免内存泄漏 ContentPage.OnReturned -= returnHandler; } }
内容的提问来源于stack exchange,提问作者Nii
相关产品推荐
相关产品推荐

