前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >C# 事件的订阅和解阅

C# 事件的订阅和解阅

作者头像
用户9127601
发布于 2021-11-01 02:22:38
发布于 2021-11-01 02:22:38
90900
代码可运行
举报
文章被收录于专栏:dotNET编程大全dotNET编程大全
运行总次数:0
代码可运行

类或对象可以通过事件向其他类或对象通知发生的相关事情。发送(或引发)事件的类称为“发布者”,接收(或处理)事件的类称为“订阅者”。

1.C#winform中使用+=和-=订阅事件和移除事件订阅

2.可以使用+=给一个控件订阅多个事件,触发事件时按顺序执行,直到使用-=移除事件订阅为止。

示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("我是过去的事件");
        }

        private void button2_Click(object sender, EventArgs e)
        {
        //方式1
            //button1.Click -= button1_Click;
            //用 lambda 表达式添加事件处理程序
            //button1.Click += (ss, ee) => MessageBox.Show("我是现在的事件");
        //方式2
            button1.Click -= button1_Click;
            this.button1.Click += new EventHandler(buttonTest_Click);
        }

        private void buttonTest_Click(object sender, EventArgs e)
        {
            MessageBox.Show("我是现在的事件");
        }

为了避免重复加载的问题,装载新事件前先把原来的事件卸载掉;

事件装载也可以简写如下;

请注意,下面的语法是 C# 2.0 中的新语法。此语法完全等效于必须使用 new 关键字显式创建封装委托的 C# 1.0 语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
this.button1.Click += buttonTest_Click;

此外还可以使用匿名方法订阅事件

如果使用匿名函数订阅事件,事件的取消订阅过程将比较麻烦。这种情况下若要取消订阅,必须返回到该事件的订阅代码,将该匿名方法存储在委托变量中,然后将此委托添加到该事件中。一般来说,如果必须在后面的代码中取消订阅某个事件,则建议您不要使用匿名函数订阅此事件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
button1.Click += delegate (object o, EventArgs e)
            {
                //string s = o.ToString() + " " + e.ToString();
                MessageBox.Show("我是现在的事件");
            };

事件即是回调,所谓回调,其实很简单,好比是这样,我需要你本例程的源码,我不知道你什么时候会结,但我希望你给我时能通知我一声,怎么通知呢? 于是我先给你我的email,你发送源码时,先查找一下我给你的email地址,然后发个邮件,这就是回调了。 也就是,我想知道你的信息,给你提供一个返回信息的渠道给我,然后你使用这个渠道联系我,这就是回调。

从一个简单的例子,来说明一下这种事件消息传递的机制!

    有一家三口,妈妈负责做饭,爸爸和孩子负责吃。。。将这三个人,想象成三个类。

   妈妈有一个方法,叫做“做饭”。有一个事件,叫做“开饭”。做完饭后,调用开饭事件,发布开饭消息。

  爸爸和孩子分别有一个方法,叫做“吃饭”。

   将爸爸和孩子的“吃饭”方法,注册到妈妈的“开饭”事件。也就是,订阅妈妈的开饭消息。让妈妈做完饭开饭时,发布吃饭消息时,告诉爸爸和孩子一声。

这种机制就是C#中的,订阅发布。下面我们用代码实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Program
    {
        public static void Main(string[] args)
        {
            //实例化对象
            Mom mom = new Mom();
            Dad dad = new Dad();
            Child child = new Child();
            
            //将爸爸和孩子的Eat方法注册到妈妈的Eat事件
            //订阅妈妈开饭的消息
            mom.Eat += dad.Eat;
            mom.Eat += child.Eat;
            
            //调用妈妈的Cook事件
            mom.Cook();
            
            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }
    }
    
    public class Mom
    {
        //定义Eat事件,用于发布吃饭消息
        public event Action Eat;
        
        public void Cook()
        {
            Console.WriteLine("妈妈 : 饭好了");
            //饭好了,发布吃饭消息
            Eat?.Invoke();
        }
    }
    
    public class Dad
    {
        public void Eat()
        {
            //爸爸去吃饭
            Console.WriteLine("爸爸 : 吃饭了。");
        }
    }
    
    public class Child
    {
        public void Eat()
        {
            //熊孩子LOL呢,打完再吃
            Console.WriteLine("孩子 : 打完这局再吃。");
        }
    }

运行结果:

当爷爷奶奶来做客了怎么办呢?和爸爸孩子一样,写个Eat方法,同样注册到妈妈的开饭事件就好了。

?. 解释:如果前面的Eat不为空,则执行后面的Invoke

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 dotNET编程大全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为了避免重复加载的问题,装载新事件前先把原来的事件卸载掉;
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档