WPF仿网易云搭建笔记(4):信息流控制之消息订阅

文章目录

专栏和Gitee仓库

WPF仿网易云 Gitee仓库
WPF仿网易云 CSDN博客专栏

前言

上一篇文章中,我们简单讲解了一下父子通讯的逻辑。父子通讯是强绑定逻辑。这里我们将讲解消息订阅通讯的方式。消息订阅一般用于之间通讯。

消息订阅

WPF消息订阅一共有两种方案,一个是Prism的方案,一个是CommunityToolkit.Mvvm的方案。

WPF Prims框架详解
WPF CommunityToolkit.Mvvm Messenger通讯

这里我们使用使用CommunityToolkit.Mvvm。使用Prism的也可以。

最简单的案例

简单用例

不了解CommunityToolkit.Mvvm的可以看这个

WPF CommunityToolkit.Mvvm Messenger通讯

这里用到了record,不了解的可以看这个文章。当然也可以用class

博客园 C# -- Record, Class, Struct

父组件订阅
csharp 复制代码
namespace BlankApp1.Views
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        
        public record MainWindowMessage(string msg);
        public MainWindowViewModel ViewModel { get; set; }

        public MainWindow()
        {
        	......其它代码
            InitializeComponent();
            //订阅MainWindowMessage的对象数据
            WeakReferenceMessenger.Default.Register<MainWindowMessage>(this,MessageRecieve);
            //也可以取消订阅,但是一般不用
            //WeakReferenceMessenger.Default.Unregister<MainWindowMessage>(this);
        }

        private void MessageRecieve(object recipient, MainWindowMessage message)
        {
            Debug.WriteLine("接受到消息"+message.msg);
        }
    }
}
子组件回调
csharp 复制代码
MiniWindow = new RelayCommand(() => {
    //其它代码逻辑,不重要
    ......
    //发送订阅消息
    WeakReferenceMessenger.Default.Send(new MainWindowMessage("缩小窗口"));
});

结果

消息订阅机制

我们模拟一个最简单的消息订阅场景。ViewA给ViewB推送消息。

消息token是A还是B?

我们推送订阅消息,需要用到Key去推送订阅。那么用的是Key_A还是Key_B呢。

这个时候,我们就要想到推送开发时候的流程了。我们一般开发都是先暴露,再使用的代码开发流程。所以我们一般是先想ViewB能做什么,先写好订阅,再写推送逻辑的。而且一般是一次订阅,多次推送。可以ViewA推送ViewB,也可以ViewC推送ViewB,ViewD推送ViewB。

所以结论:用到token是订阅者的token。是token_B

传递消息的载体。

我们传递消息,需要考虑到载体的问题。我们为了简化代码,一般消息载体都是用string字符串作为载体。使用Json格式传递。通过序列化和反序列化来进行区别。

这里我推荐使用Newtonsoft。这里不展开说明

双重token

CommunityToolkit.Mvvm8.1 消息通知(4)
【CommunityToolkit.Mvvm】Messenger 信使

如果是单一Token,只能做到View的订阅。如果是双重Token,我们可以做到View的某个函数的订阅。极大得增强了函数的复用性。这里我建议使用Enum枚举类型作为token

csharp 复制代码
/// <summary>
/// 消息订阅载体
/// </summary>
/// <param name="Msg"></param>
public record MainWindowMessage(string Msg);

//声明enum枚举类型
public enum MainWindowMessageToken { Test1, Test2 }

//双重token订阅
WeakReferenceMessenger.Default.Register<MainWindowMessage, string>(this, MainWindowMessageToken.Test1.ToString(), MessageRecieve);


//使用token双重推送
WeakReferenceMessenger.Default.Send(new MainWindowMessage("缩小窗口"), MainWindowMessageToken.Test1.ToString());

重复订阅问题

如果重复订阅,会主动抛出异常

结论

我们消息流已经基本解决了。

  • 强关联:父子通讯:组件化通讯
  • 弱关联:消息订阅:页与页,窗口与窗口

我们最后的信息流控制就是IOC容器了,IOC容器解决了之后,我们已经将WPF完全解耦,所有复杂的WPF问题都可以变成简单的单一问题。

相关推荐
2501_926978332 小时前
AGI 的四种瓶颈:资源型还是发现型--以及DSH的位置
人工智能·经验分享·笔记·ai写作
liuqs3324 小时前
nat123安卓和nat123全端口选型指南,映射工具怎么挑
网络·笔记
xian_wwq4 小时前
【学习笔记】光伏“四可”装置纵密模块--配置方法和原理
笔记·学习
日拱一卒的小田7 小时前
ZYNQ学习笔记3-ZYNQ的IIC控制器1
笔记·单片机·学习
不会代码的小猴8 小时前
C++新增关键字
开发语言·c++·笔记
LuminousCPP8 小时前
栈和队列专题(一):LeetCode 20. 有效的括号
数据结构·经验分享·笔记·leetcode·手写栈
小赵AI手记11 小时前
技术拆解(十七)具身智能:机器人动作生成为何走向Diffusion Policy?
人工智能·笔记·python·机器人
深蓝海拓11 小时前
基于socket的 TCP上位机通信内容解析程序
网络·笔记·python·学习·tcp/ip·plc
疯狂打码的少年11 小时前
【数据结构】二叉排序树(BST)的定义与操作
数据结构·笔记·算法
蒸蒸yyyyzwd11 小时前
后端面经学习笔记
笔记·学习