Xamarin Forms中如何等待第二页关闭后再执行后续流程
为啥现在流程乱了?
你用的await Navigation.PushAsync()只是把页面塞进导航栈,但根本不会等用户关掉这个页面就继续跑后面的代码——所以InRec()、推FrmComplete、推MainVerifyPage会瞬间执行完,用户直接看到最后一个MainVerifyPage,返回时才会依次看到前面的页面,完全不是你要的顺序。
怎么改才能符合需求?
核心是要等用户关掉当前页面后再执行下一步,PushAsync做不到这点,得换模态弹窗+等待关闭的逻辑,给你两种常用方案:
方案一:给弹窗加个“等待关闭”的方法
这种方式最直接,先改弹窗页面(拿FrmInProgress举例):
public class FrmInProgress : ContentPage { private TaskCompletionSource<bool> _closeTask; // 对外提供一个等待关闭的Task public Task WaitForUserClose() { _closeTask = new TaskCompletionSource<bool>(); return _closeTask.Task; } // OK按钮的点击事件 private void OkBtn_Clicked(object sender, EventArgs e) { // 标记任务完成,通知调用方可以继续了 _closeTask?.SetResult(true); // 关闭当前模态页面 Navigation.PopModalAsync(); } }
然后改你的InitDownload方法,用PushModalAsync打开弹窗,等用户关掉再走下一步:
private async Task InitDownload() { bool isInboundExist = true; // 这里假设条件成立 if (isInboundExist) { // 打开进度页,等用户点OK关闭 var progressPage = new FrmInProgress(); await Navigation.PushModalAsync(progressPage); await progressPage.WaitForUserClose(); // 执行InRec流程 InRec(); // 打开完成页,同样等用户关闭 var completePage = new FrmComplete(); await Navigation.PushModalAsync(completePage); await completePage.WaitForUserClose(); // 最后跳转到MainVerifyPage await Navigation.PushAsync(new MainVerifyPage()); // 如果不想让用户返回之前的页面,可以清空栈再跳转: // await Navigation.PopToRootAsync(); // await Navigation.PushAsync(new MainVerifyPage()); } }
方案二:用消息中心监听页面关闭
要是不想改弹窗的结构,就用MessagingCenter来传关闭信号:
先在弹窗的OK点击事件里发消息:
private void OkBtn_Clicked(object sender, EventArgs e) { // 发送页面关闭的消息,带上页面类型标识 MessagingCenter.Send(this, "PageClosed", this.GetType().Name); Navigation.PopModalAsync(); }
然后在InitDownload里监听消息,等消息来了再继续:
private async Task InitDownload() { bool isInboundExist = true; if (isInboundExist) { // 准备等待进度页关闭的信号 var waitProgressClose = new TaskCompletionSource<bool>(); MessagingCenter.Subscribe<FrmInProgress, string>(this, "PageClosed", (sender, pageName) => { if (pageName == nameof(FrmInProgress)) { waitProgressClose.SetResult(true); MessagingCenter.Unsubscribe<FrmInProgress, string>(this, "PageClosed"); } }); // 打开进度页 await Navigation.PushModalAsync(new FrmInProgress()); // 等用户关闭 await waitProgressClose.Task; // 执行InRec InRec(); // 同样处理完成页 var waitCompleteClose = new TaskCompletionSource<bool>(); MessagingCenter.Subscribe<FrmComplete, string>(this, "PageClosed", (sender, pageName) => { if (pageName == nameof(FrmComplete)) { waitCompleteClose.SetResult(true); MessagingCenter.Unsubscribe<FrmComplete, string>(this, "PageClosed"); } }); await Navigation.PushModalAsync(new FrmComplete()); await waitCompleteClose.Task; // 跳转到目标页面 await Navigation.PushAsync(new MainVerifyPage()); } }
关键点总结
await必须用,但不是等PushAsync完成,而是要等用户关闭页面的动作完成。- 用
PushModalAsync比PushAsync更合适,因为模态页面会强制用户先处理当前页面,不能点别的,符合你这个流程的要求。 - 最后跳转MainVerifyPage时,如果不需要保留之前的页面栈,可以清空栈再跳转,避免用户返回时看到一堆没用的页面。
内容的提问来源于stack exchange,提问作者DANIELKT
相关产品推荐
相关产品推荐

