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事件未触发。
复现步骤
- 执行
Shell.Current.GoToAsync("Page")进入Page页面 - 在Page中执行
Shell.Current.Navigation.PushModalAsync(new Page2());弹出模态页 - 在Page2中执行
Shell.Current.Navigation.PopModalAsync();关闭模态页 - 观察到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
相关产品推荐
相关产品推荐

