分享

C# 事件的订阅和解阅

 ontheroad96j47 2021-11-08

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

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

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

示例:

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 语法:

this.button1.Click += buttonTest_Click;

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

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

button1.Click += delegate (object o, EventArgs e) { //string s = o.ToString() + " " + e.ToString(); MessageBox.Show("我是现在的事件"); };

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

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

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

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

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

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

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

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

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多