WinUI 3中使用MVVM Toolkit请求消息失败问题排查
问题根源
你的代码存在两个核心问题导致请求返回null:
UserSenderViewModel未实例化:你只是在ViewModelRequestMessenger中定义了这个嵌套类,但从未创建它的实例,没有接收器响应消息请求。ObservableRecipient未激活:ObservableRecipient的OnActivated方法仅在IsActive属性设为true时才会执行,你的消息注册逻辑因此从未运行。
修复方案
1. 实例化并激活消息接收器
修改ViewModelRequestMessenger,添加UserSenderViewModel的实例并设置IsActive = true,确保消息注册逻辑执行:
public class ViewModelRequestMessenger : ObservableObject { // 实例化并激活消息发送者ViewModel private readonly UserSenderViewModel _userSender = new() { IsActive = true }; public class UserSenderViewModel : ObservableRecipient { public string Username { get; private set; } = "Bob"; protected override void OnActivated() { Messenger.Register<UserSenderViewModel, CurrentUsernameRequestMessage>(this, (r, m) => m.Reply(r.Username)); } } private string username; public string Username { get => username; private set => SetProperty(ref username, value); } public void RequestCurrentUsername() { Username = WeakReferenceMessenger.Default.Send<CurrentUsernameRequestMessage>(); } public void ResetCurrentUsername() { Username = null; } public sealed class CurrentUsernameRequestMessage : RequestMessage<string> { } }
2. 可选优化:调整类结构(更清晰)
嵌套类写法可行,但将UserSenderViewModel抽为独立类会让代码结构更直观:
// 独立的消息发送者ViewModel public class UserSenderViewModel : ObservableRecipient { public string Username { get; private set; } = "Bob"; protected override void OnActivated() { Messenger.Register<UserSenderViewModel, CurrentUsernameRequestMessage>(this, (r, m) => m.Reply(r.Username)); } } public class ViewModelRequestMessenger : ObservableObject { private readonly UserSenderViewModel _userSender = new() { IsActive = true }; // 原有属性和方法保持不变 private string username; public string Username { get => username; private set => SetProperty(ref username, value); } public void RequestCurrentUsername() { Username = WeakReferenceMessenger.Default.Send<CurrentUsernameRequestMessage>(); } public void ResetCurrentUsername() { Username = null; } public sealed class CurrentUsernameRequestMessage : RequestMessage<string> { } }
关键说明
ObservableRecipient激活规则:必须手动将IsActive设为true,否则OnActivated不会触发,消息注册逻辑不会生效。- 消息请求逻辑:
WeakReferenceMessenger.Default.Send<T>()会遍历所有注册该消息的接收器,若没有匹配的接收器,会返回对应类型的默认值(string类型默认值为null),这就是你看到返回null的直接原因。
内容的提问来源于stack exchange,提问作者user21632369
相关产品推荐
相关产品推荐

