观察者模式实践-实现winform 窗体之间传值(事件实现)

2023-11-12

事件本身就是观察者模式的一个实现。
先总结一下事件的使用:

  • 委托类型声明
  • 定义发布者类,并声明事件
  • 在发布者类中定义触发事件方法
  • 定义订阅者类,并注册事件
  • 在订阅者类中定义事件处理方法

针对事件,.Net Framework提供了一个标准模式,主要在winform中比较常见,区别就是不用自定义委托,使用EventHander委托,因此其步骤是:

  • 定义发布者类,并声明事件
  • 在发布者类中定义触发事件方法
  • 定义订阅者类,并注册事件
  • 在订阅者类中定义事件处理方法

上述步骤是在委托方法中不传参的情况,如果需要传递参数,则需要自定义EventHander中的EventArgs对象,并使用泛型委托EventHander,其步骤是:

  • 定义类,继承自EventArgs,目的是为了加属性传参
  • 定义发布者类: 事件的定义,使用自定义类的EventHander泛型委托
  • 在发布者类中定义 触发事件的方法,在这个方法中填充需要传递的参数,给1中自定义类的属性赋值
  • 定义订阅者类: 订阅事件
  • 订阅者: 事件处理的方法,使用委托传过来的参数(继承自EventArgs类的属性)

使用事件实现winform窗体传值感觉比使用简单方法,在发布者类中维护订阅者类列表要简单一点;
而且后期扩展要更容易。
实例:本实例定义一个winform程序,有三个窗体,实现frmMain中的textbox更新内容,frmSub1和frmSub2中的textbox同样更新内容,以下是示例代码:

FrmMain的代码:
namespace SendMessageWithEvent
{
    /// <summary>
    /// 委托,事件处理程序的方法的参数和返回值必须要与该委托一致
    /// </summary>
    /// <param name="message"></param>
    public delegate void MsgHander(string message);

    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 定义事件
        /// </summary>
        public event MsgHander SendMsgEvent;


        private void txtMessage_TextChanged(object sender, EventArgs e)
        {
            string msg = txtMessage.Text;
            //触发事件
            SendMsgEvent(msg);
        }
    }
}
FrmSub1的代码:
namespace SendMessageWithEvent
{
    public partial class FrmSub1 : Form
    {
        /// <summary>
        /// 当前窗体是否处于显示状态
        /// </summary>
        private bool isShown = false;

        /// <summary>
        /// 用于关闭窗体时,移除事件监听
        /// </summary>
        private FrmMain _frmMain;

        public FrmSub1(FrmMain frmMain)
        {
            _frmMain = frmMain;

            //注册事件处理程序
            _frmMain.SendMsgEvent += ChangeMsg;

            InitializeComponent();

        }

        /// <summary>
        /// 事件处理程序
        /// </summary>
        /// <param name="message"></param>
        private void ChangeMsg(string message)
        {
            if (isShown==false)
            {
                this.Show();
                isShown = true;
            }
            txtMessage.Text = "Sub1: "+ message;
        }

        /// <summary>
        /// 窗体关闭时,移除事件监听
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmSub1_FormClosing(object sender, FormClosingEventArgs e)
        {
            _frmMain.SendMsgEvent -= ChangeMsg;
        }
    }
}

namespace SendMessageWithEvent
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            FrmMain frmMain = new FrmMain();
            FrmSub1 frmSub1 = new FrmSub1(frmMain);
            FrmSub2 frmSub2 = new FrmSub2(frmMain);
            
            Application.Run(frmMain);
        }
    }
}

完整源代码参考:https://gitee.com/Alexander360/ProDotnetDesignPatternFramework45

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

观察者模式实践-实现winform 窗体之间传值(事件实现) 的相关文章

随机推荐

  • 死锁产生的四个必要条件(缺一不可)

    死锁产生必须同时满足四个条件 只要其中任意一条不成立 死锁就不会发生 1 互斥条件 进程要求对所分配的资源进行排他性控制 即在一段时间内某项资源只被 一个进程所占有 此时若有其他进程请求该资源 则请求进程只能等待 如图一 2 非抢占 进程所
  • 解决OptiSystem安装、使用过程中遇到的问题

    系统环境 Win10系统 问题1 在上一篇文章 Optisystem7 0安装教程 Win10系统 中提到 安装过程中会弹出一个对话框 需要点击 忽略 但是安装过程中出现下图错误 错误代码 0x3 点击忽略 仍然会继续弹出这个对话框 或者第
  • Flink实战-(1)Flink-CDC MySQL同步到MySQL(select)

    背景 基于select语句的Flink CDC 适用于数据同步的全量同步的场景 可以结合 Azkaban 或者dolphin scheduler 做定时调度 T 1 数据同步 1 maven
  • Verdi之nTrace/nSchema

    目录 3 nTrace介绍 3 1 启动Verdi 3 2查看Verdi中的设计结构 3 3查看Verdi中的验证结构 3 4 查找模块和trace信号 3 5 查找string 3 6 信号drive load 3 7 快速查看设计有哪些
  • 使用 javascript 将鼠标指针移动到特定位置

    请注意 无法将鼠标指针移动到 JavaScript 中的特定位置 主要原因是它会给用户带来安全问题并损害用户体验 在这篇文章中 我们将创建一个假的或自定义的鼠标指针 它可能看起来类似于默认系统的鼠标指针 然后我们将使用 JavaScript
  • 使用TensorBoard可视化模型

    为了了解发生的情况 我们在模型训练期间打印一些统计数据 以了解训练是否在进行中 但是 我们可以做得更好 PyTorch 与 TensorBoard 集成在一起 TensorBoard 是一种工具 用于可视化神经网络训练运行的结果 读取数据并
  • Q81:“三角形网格”之“PLY文件”

    81 1 引入 在 Q79 和 Q80 中用三角形网格细分曲面时 都是将每一个三角形的三个顶点的坐标都保存在内存中 这句话有两个重点 其一 每个三角形的三个顶点的坐标都计算了一次 但是 每个顶点都是被好几个三角形公用的 所以每个顶点的坐标被
  • 试题:网易笔试的一道题目

    写一个程序 打印出以下的序列 a b c d e z a b a c a d a e a z b c b d b z c d y z a b c a b d a b z a c d x y z a b c d x y z 这道题是从luci
  • mysql通用日志不打印_解决logback不打印mybatis的SQL日志的问题

    工作这么多年 今天还是因为Logback的这个问题稍微卡了一下 惭愧 问题描述 logback配置了如下信息 此处省略File Appender内容 logbase sql d yyyy MM dd log 30 d yyyy MM dd
  • SQL 语句中 where 条件后 写上1=1 是什么意思

    在编程过程中 经常会在代码中使用到 where 1 1 这是为什么呢 SQL注入 初次看到这种写法的同学肯定很纳闷 加不加where 1 1 查询不都一样吗 例如 select from customers 与 select from cu
  • Windows/Linux 部署Nacos遇到的问题及解决方法

    nacos的版本采用的是2 1 2 本片只记录部署过程遇到的问题 不涉及部署过程 Linux遇到的问题 com alibaba nacos core distributed raft exception JRaftException jav
  • C++项目(有注释超详细)

    规范代码 定义函数或者类尽量放到头文件中 这样不容易出现重复命名和代码冗杂的问题 pragma once include
  • 全新的eMPP(Elastic MPP),超越MPP的超弹性架构

    大数据时代 的概念最早由著名咨询公司麦肯锡提出 麦肯锡表示 数据已渗透到今天的每个行业和业务功能领域 并已成为重要的生产要素 数据在精巧的算法中被挖掘 数据分析变得至关重要 大家开始达成一个共识 数据计算 能够找到新发现 博思艾伦咨询公司的
  • 第1174期AI100_机器学习日报(2017-12-05)

    AI100 机器学习日报 2017 12 05 kegra 使用keras通过深度学习构建知识图谱 ChatbotsChina 图数据中的推理 微软亚洲研究院 浅谈NLP中条件语言模型 Conditioned Language Models
  • 第七课:BootRom的烧录

    目录 2 5 烧录BootRom 2 5 1 P2020 e500核 上电启动及boot流程 2 5 2 烧录BootRom到NorFlash 2 5 2 1 CodeWarrior的介绍
  • QT定时器

    QTimer使用 添加头文件 include
  • 推荐一个很适合程序员的副业!

    推荐一个超级赞的副业就是有声书录制 从2013年到现在已经火了9年时间 可谓是源远流长 这个兴趣爱好衍生出来的副业已经承载了上百万小白从业人员 头部主播的年收入都破了百万 有声书录制的发展历程可以概括为 或许曾经混沌 但必定未来可期 判断一
  • windows核心编程-杨波-专题视频课程

    windows核心编程 422人已学习 课程介绍 SDK 软件开发工具包 Software Development Kit SDK 一般是一些被软件工程师用于为特定的软件包 软件框架 硬件平台 作业系统等创建应用软件的开发工具的集合 MFC
  • Go语言基础(一)之函数调用、传参、反射机制、类型断言与转换

    Go语言基础 一 之函数调用 传参 反射机制 1 1 函数调用 package main func myFunction a b int int int return a b a b func main myFunction 66 77 使
  • 观察者模式实践-实现winform 窗体之间传值(事件实现)

    事件本身就是观察者模式的一个实现 先总结一下事件的使用 委托类型声明 定义发布者类 并声明事件 在发布者类中定义触发事件方法 定义订阅者类 并注册事件 在订阅者类中定义事件处理方法 针对事件 Net Framework提供了一个标准模式 主