You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 10:25:26