Xamarin.Forms中MessagingCenter消息发送成功但无法接收的问题
问题原因
你的MessagingCenter消息无法被接收是实现位置错误导致的:
- 你把
MessagingCenter.Subscribe订阅代码写在了Counter属性的set块中,该代码块仅当Counter属性被外部主动赋值时才会执行。在常规的数据绑定场景下,这个setter从来没有被触发过,订阅逻辑从未生效,自然收不到发送的消息。 - 把订阅放在属性setter中还存在隐性bug:如果后续Counter被多次赋值,会重复创建多个订阅回调,同一条消息会触发多次重复更新,还会造成内存泄漏。
修复步骤
- 将消息订阅逻辑移动到
AppShellViewModel的构造函数中,保证ViewModel初始化时就完成仅一次的订阅注册 - 回调中直接给Counter属性赋值,复用属性的setter触发
OnPropertyChanged通知UI更新,不要在回调里直接改私有字段 - 在ViewModel生命周期结束时(比如对应页面销毁、OnDisappearing阶段)调用取消订阅方法,避免内存泄漏
修复后的AppShellViewModel完整代码:
internal class AppShellViewModel : BaseViewModel { private int counter = 0; public int Counter { get => counter; set { counter = value; OnPropertyChanged(); } } public AppShellViewModel() { // 初始化时一次性注册订阅 MessagingCenter.Subscribe<Panier, int>(this, "update counter", (sender, cartCount) => { // 直接使用消息传递过来的计数值即可,不需要重复调用CountPanier计算 Counter = cartCount; }); } /// <summary> /// 页面销毁时调用,清理订阅 /// </summary> public void Dispose() { MessagingCenter.Unsubscribe<Panier, int>(this, "update counter"); } }
可选优化
你代码中使用的ObservableCollection本身自带集合变更通知,如果不需要跨完全隔离的模块传值,完全可以不用MessagingCenter:直接在Panier类中监听content.CollectionChanged事件,在集合增删时更新计数属性,绑定链路会更短更易维护。如果你的架构确实需要跨ViewModel松耦合传值,上面修复后的MessagingCenter代码可以正常工作。
内容的提问来源于stack exchange,提问作者Maurice Filiatreault Hebert
相关产品推荐
相关产品推荐

