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

MAUI Shell模态页关闭后Appearing事件未触发问题咨询

关于Shell导航中模态页关闭后原页面Appearing事件未触发的问题

问题描述

通过Shell.Current.GoToAsync("Page");导航至Page页面时,Page的跨平台事件Appearing会被触发;通过Shell.Current.Navigation.PopAsync();返回Page时,该事件同样会触发。但在Page中通过Shell.Current.Navigation.PushModalAsync(new Page2());弹出模态页Page2,在Page2中调用Shell.Current.Navigation.PopModalAsync();关闭模态页后,Page的Appearing事件未触发。

复现步骤

  1. 执行Shell.Current.GoToAsync("Page")进入Page页面
  2. 在Page中执行Shell.Current.Navigation.PushModalAsync(new Page2());弹出模态页
  3. 在Page2中执行Shell.Current.Navigation.PopModalAsync();关闭模态页
  4. 观察到Page的Appearing事件未触发

解答

这是预期设计还是Bug?

这是预期设计。

模态页面是在当前页面上方叠加显示的视图,原Page并没有被从导航栈移除,也没有进入不可见状态(仅视觉上被覆盖)。而Appearing事件的触发条件是页面从不可见状态切换为可见状态,因此模态页关闭后,原Page的Appearing事件不会再次触发。

如何监听Page重新显示的时机?

可以通过以下几种方式实现需求:

1. 监听导航栈的ModalPopped事件

在目标Page中注册导航的ModalPopped事件,当任何模态页被关闭时都会触发该事件,可在回调中执行对应逻辑:

public Page()
{
    InitializeComponent();
    // 订阅模态页关闭事件
    Navigation.ModalPopped += OnModalPopped;
}

private void OnModalPopped(object sender, ModalPoppedEventArgs e)
{
    // 可判断关闭的是否是目标模态页(可选)
    if (e.Modal is Page2)
    {
        // 执行模态页关闭后需要的操作
    }
}

// 页面销毁时取消订阅,避免内存泄漏
protected override void OnDisappearing()
{
    base.OnDisappearing();
    Navigation.ModalPopped -= OnModalPopped;
}

2. 使用弱引用消息传递(WeakReferenceMessenger)

通过消息传递机制,在模态页关闭时主动通知原Page执行操作:

  • 首先定义消息类:
    public class ModalClosedMessage
    {
        // 可添加需要传递的参数(可选)
    }
    
  • 在原Page中订阅消息:
    public Page()
    {
        InitializeComponent();
        WeakReferenceMessenger.Default.Register<ModalClosedMessage>(this, (recipient, message) =>
        {
            // 执行模态页关闭后的操作
        });
    }
    
    protected override void OnDisappearing()
    {
        base.OnDisappearing();
        // 取消订阅
        WeakReferenceMessenger.Default.Unregister<ModalClosedMessage>(this);
    }
    
  • 在模态页Page2中关闭时发送消息:
    private async void CloseModalButton_Clicked(object sender, EventArgs e)
    {
        await Shell.Current.Navigation.PopModalAsync();
        // 发送消息通知原页面
        WeakReferenceMessenger.Default.Send(new ModalClosedMessage());
    }
    

3. 直接在模态页关闭后执行逻辑

如果是在原Page中主动打开的模态页,可以利用PushModalAsync的异步特性,在模态页关闭后直接执行操作:

private async void OpenModalButton_Clicked(object sender, EventArgs e)
{
    // 打开模态页,等待模态页关闭
    await Shell.Current.Navigation.PushModalAsync(new Page2());
    // 模态页关闭后会执行到这里,直接调用需要的方法
    HandleModalReturned();
}

private void HandleModalReturned()
{
    // 执行模态页关闭后的操作
}

内容的提问来源于stack exchange,提问作者JGlumanda

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:40:36