时间:2022年05月16日 | 作者 : aaronyang | 分类 : wpf in net6 | 浏览: 692次 | 评论 0 人
由于8.0预览版有些重名的bug,提示波浪,说二重性的错误CS0229
可空类型警告
消息实例的另一个有用特性是它们也可以用于从一个模块向另一个模块请求值。 为了做到这一点,该包包含一个基本的 RequestMessage<T> 类,可以像这样使用它:
场景: 以前的send 都是没有返回值的,现在如果需要返回值,你的消息就要继承RequestMessage<T> 其中的T就是返回的值的类型
比如我们注册了一个消息,返回一个Teacher
我们需要定义消息体Teacher,然后用TeacherRequestMessage : RequestMessage<Teacher> 包装下
public class Teacher { public string TeacherName { get; set; } } public class TeacherRequestMessage : RequestMessage<Teacher> { }
接下来注册消息有点不一样
打开twowindowviewmodel.cs
public partial class TwoWindowViewModel : ObservableRecipient { protected override void OnActivated() { WeakReferenceMessenger.Default.Register<ShowLoginMessage>(this, (r, m) => { InputCode = m.LoginName; }); WeakReferenceMessenger.Default.Register<ShowLoginMessage, string>(this, "TwoWindowViewModel_show1", (r, m) => { InputCode = "当前登陆:" + m.LoginName; }); WeakReferenceMessenger.Default.Register<ShowLoginMessage, string>(this, "TwoWindowViewModel_show2", (r, m) => { InputCode = "当前2登陆:" + m.LoginName; }); WeakReferenceMessenger.Default.Register<TwoWindowViewModel, TeacherRequestMessage>(this, (r, m) => { m.Reply(new Teacher { TeacherName = "杨老师" }); }); WeakReferenceMessenger.Default.Register<TwoWindowViewModel, TeacherRequestMessage,string>(this,"returnTeacher", (r, m) => { m.Reply(new Teacher { TeacherName = "杨老师带token的" }); }); }
接下来send,在MainWindow里新增2个按钮,一个不带token的,一个调用带token的
private void Show7_Click(object sender, RoutedEventArgs e) { Teacher teacher = WeakReferenceMessenger.Default.Send<TeacherRequestMessage>(); MessageBox.Show(teacher.TeacherName); } private void Show8_Click(object sender, RoutedEventArgs e) { //Teacher teacher = WeakReferenceMessenger.Default.Send<TeacherRequestMessage,string>(new TeacherRequestMessage(), "returnTeacher"); Teacher teacher = WeakReferenceMessenger.Default.Send(new TeacherRequestMessage(), "returnTeacher"); MessageBox.Show(teacher.TeacherName); }
这里要注意一个异常,当twowindow窗体没打开,send带返回值的,会报异常,所以这里要判断下消息是否注册了,还有个事,
通过这个判断
WeakReferenceMessenger.Default.IsRegistered
先显示窗体,消息被注册了,单击 获取值的消息按钮,正常,然后关闭了TwoWindow后,消息竟然还能send
不过弱引用的,内存应该会回收的,为了防止泄露,我手动unload取消注册所有消息
由于注册是在ViewModel注册是在vm注册的,所以只能vm取消了,我尝试如下成功
using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; namespace AyWpfNet6 { /// <summary> /// TwoWindow.xaml 的交互逻辑 /// </summary> public partial class TwoWindow : Window { public TwoWindow(ILogger<TwoWindow> logger) { InitializeComponent(); this.Unloaded += TwoWindow_Unloaded; } private void TwoWindow_Unloaded(object sender, RoutedEventArgs e) { this.Unloaded -= TwoWindow_Unloaded; WeakReferenceMessenger.Default.Send("1","unregistertwowindow"); } } }
using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.Mvvm.Messaging; using CommunityToolkit.Mvvm.Messaging.Messages; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace AyWpfNet6.ViewModels { public class Teacher { public string TeacherName { get; set; } } public class TeacherRequestMessage : RequestMessage<Teacher> { } public partial class TwoWindowViewModel : ObservableRecipient { protected override void OnActivated() { WeakReferenceMessenger.Default.Register<ShowLoginMessage>(this, (r, m) => { InputCode = m.LoginName; }); WeakReferenceMessenger.Default.Register<ShowLoginMessage, string>(this, "TwoWindowViewModel_show1", (r, m) => { InputCode = "当前登陆:" + m.LoginName; }); WeakReferenceMessenger.Default.Register<ShowLoginMessage, string>(this, "TwoWindowViewModel_show2", (r, m) => { InputCode = "当前2登陆:" + m.LoginName; }); WeakReferenceMessenger.Default.Register<TwoWindowViewModel, TeacherRequestMessage>(this, (r, m) => { m.Reply(new Teacher { TeacherName = "杨老师" }); }); WeakReferenceMessenger.Default.Register<TwoWindowViewModel, TeacherRequestMessage,string>(this,"returnTeacher", (r, m) => { m.Reply(new Teacher { TeacherName = "杨老师带token的" }); }); WeakReferenceMessenger.Default.Register<string, string>(this, "unregistertwowindow", (r, m) => { this.IsActive = false; }); } protected override void OnDeactivated() { base.OnDeactivated(); //WeakReferenceMessenger.Default.Unregister<ShowLoginMessage>(this); WeakReferenceMessenger.Default.UnregisterAll(this); } // Register that specific message... //WeakReferenceMessenger.Default.Register<LoggedInUserChangedMessage>(this); //// ...or alternatively, register all declared handlers //WeakReferenceMessenger.Default.RegisterAll(this); //// Send a message from some other module //WeakReferenceMessenger.Default.Send(new LoggedInUserChangedMessage(user)); //// Unregisters the recipient from a message type //WeakReferenceMessenger.Default.Unregister<LoggedInUserChangedMessage>(this); //// Unregisters the recipient from a message type in a specified channel //WeakReferenceMessenger.Default.Unregister<LoggedInUserChangedMessage, int>(this, 42); //// Unregister the recipient from all messages, across all channels //WeakReferenceMessenger.Default.UnregisterAll(this); [ObservableProperty] private string inputCode; public TwoWindowViewModel() { IsActive = true; } [ICommand] public void ShowCode() { WeakReferenceMessenger.Default.Send<MessageBase>(new MessageBase { Code = "AY1991来自TwoWindowViewModel", Value = "来自twowindow" }); } } }
设置了IsActive=false后,会触发Deactivated事件,此时就取消注册了
一般来说,注册消息,都在xaml.cs中注册
接下来测试带参数的,然后返回值的send
public class TeacherRequestMessage : RequestMessage<Teacher> { public string TeacherId { get; set; } }
WeakReferenceMessenger.Default.Register<TwoWindowViewModel, TeacherRequestMessage, string>(this, "returnTeacher", (r, m) => { if (m.TeacherId == "1") { m.Reply(new Teacher { TeacherName = "杨老师带token的" + "id=1" }); } else { m.Reply(new Teacher { TeacherName = "十年老师带token的" + "id=任意" }); } });
MainWindow.xaml.cs
private void Show8_Click(object sender, RoutedEventArgs e) { //Teacher teacher = WeakReferenceMessenger.Default.Send<TeacherRequestMessage,string>(new TeacherRequestMessage(), "returnTeacher"); Teacher teacher = WeakReferenceMessenger.Default.Send(new TeacherRequestMessage { TeacherId="1"}, "returnTeacher"); MessageBox.Show(teacher.TeacherName); }
TeacherId传入1,返回第一个,传入其他的,就是十年老师了
====================www.ayjs.net 杨洋 wpfui.com ayui ay aaronyang=======请不要转载谢谢了。=========
同样的CollectionRequestMessage类型,一次可以返回一个列表,AY通过F12查看类型定义摸索学习的
定义消息体
public class ModuleMenu { public string MenuName { get; set; } public Action MenuCommand { get; set; } } public class ModuleMenuCollectionMessage : CollectionRequestMessage<ModuleMenu> { public string ModuleId { get; set; } }
注册消息
WeakReferenceMessenger.Default.Register<TwoWindowViewModel, ModuleMenuCollectionMessage>(this, (r, m) => { if (m.ModuleId == "1") { m.Reply(new ModuleMenu { MenuCommand=()=> { },MenuName="新建" }); m.Reply(new ModuleMenu { MenuCommand = () => { }, MenuName = "保存" }); m.Reply(new ModuleMenu { MenuCommand = () => { }, MenuName = "关闭" }); } else { m.Reply(new ModuleMenu { MenuCommand = () => { }, MenuName = "帮助" }); m.Reply(new ModuleMenu { MenuCommand = () => { }, MenuName = "关于" }); } });
根据模块id,返回一个列表
private void Show9_Click(object sender, RoutedEventArgs e) { //Teacher teacher = WeakReferenceMessenger.Default.Send<TeacherRequestMessage,string>(new TeacherRequestMessage(), "returnTeacher"); var module = WeakReferenceMessenger.Default.Send(new ModuleMenuCollectionMessage { ModuleId = "1" }); System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (var item in module) { sb.Append(item.MenuName); } MessageBox.Show(sb.ToString()); }
效果
同样的还有异步的两个
把第二个改成异步的
public class ModuleMenuCollectionMessage : AsyncCollectionRequestMessage<ModuleMenu> { public string ModuleId { get; set; } }
private async void Show9_Click(object sender, RoutedEventArgs e) { System.Text.StringBuilder sb = new System.Text.StringBuilder(); await foreach (var item in WeakReferenceMessenger.Default.Send<ModuleMenuCollectionMessage>(new ModuleMenuCollectionMessage { ModuleId = "1" })) { sb.Append(item.MenuName); } //CancellationTokenSource cts = new CancellationTokenSource(); //await foreach (var item in WeakReferenceMessenger.Default.Send<ModuleMenuCollectionMessage>(new ModuleMenuCollectionMessage { ModuleId = "1" }).WithCancellation(cts.Token)) //{ // sb.Append(item.MenuName); //} MessageBox.Show(sb.ToString()); }
你也可以这样调用
var response= await WeakReferenceMessenger.Default.Send<ModuleMenuCollectionMessage>(new ModuleMenuCollectionMessage { ModuleId = "1" }).GetResponsesAsync(); foreach (var item in response) { sb.Append(item.MenuName); }
其他的不变,如果取消参考下面的注释的,关于Cancel的用法,参考CancellationTokenSource.Cancel Method (System.Threading) | Microsoft Docs
推荐您阅读更多有关于“wpf in net6,”的文章
抖音:wpfui 工作wpf
目前在合肥企迈科技公司上班,加我QQ私聊
2023年11月网站停运,将搬到CSDN上
AYUI8全源码 Github地址:前往获取
杨洋(AaronYang简称AY,安徽六安人)和AY交流
高中学历,2010年开始web开发,2015年1月17日开始学习WPF
声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费
查看捐赠AYUI7.X MVC教程 更新如下:
第一课 第二课 程序加密教程
额 本文暂时没人评论 来添加一个吧
发表评论