類(lèi)或對象可以通過(guò)事件向其他類(lèi)或對象通知發(fā)生的相關(guān)事情。發(fā)送(或引發(fā))事件的類(lèi)稱(chēng)為“發(fā)布者”,接收(或處理)事件的類(lèi)稱(chēng)為“訂閱者”。
1.C#winform中使用+=和-=訂閱事件和移除事件訂閱
2.可以使用+=給一個(gè)控件訂閱多個(gè)事件,觸發(fā)事件時(shí)按順序執行,直到使用-=移除事件訂閱為止。
示例:
private void button1_Click(object sender, EventArgs e) { MessageBox.Show("我是過(guò)去的事件"); }
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("我是現在的事件"); }事件裝載也可以簡(jiǎn)寫(xiě)如下;
請注意,下面的語(yǔ)法是 C# 2.0 中的新語(yǔ)法。此語(yǔ)法完全等效于必須使用 new 關(guān)鍵字顯式創(chuàng )建封裝委托的 C# 1.0 語(yǔ)法:
this.button1.Click += buttonTest_Click;此外還可以使用匿名方法訂閱事件
如果使用匿名函數訂閱事件,事件的取消訂閱過(guò)程將比較麻煩。這種情況下若要取消訂閱,必須返回到該事件的訂閱代碼,將該匿名方法存儲在委托變量中,然后將此委托添加到該事件中。一般來(lái)說(shuō),如果必須在后面的代碼中取消訂閱某個(gè)事件,則建議您不要使用匿名函數訂閱此事件。
button1.Click += delegate (object o, EventArgs e) { //string s = o.ToString() + " " + e.ToString(); MessageBox.Show("我是現在的事件"); };事件即是回調,所謂回調,其實(shí)很簡(jiǎn)單,好比是這樣,我需要你本例程的源碼,我不知道你什么時(shí)候會(huì )結,但我希望你給我時(shí)能通知我一聲,怎么通知呢? 于是我先給你我的email,你發(fā)送源碼時(shí),先查找一下我給你的email地址,然后發(fā)個(gè)郵件,這就是回調了。 也就是,我想知道你的信息,給你提供一個(gè)返回信息的渠道給我,然后你使用這個(gè)渠道聯(lián)系我,這就是回調。
從一個(gè)簡(jiǎn)單的例子,來(lái)說(shuō)明一下這種事件消息傳遞的機制!
有一家三口,媽媽負責做飯,爸爸和孩子負責吃。。。將這三個(gè)人,想象成三個(gè)類(lèi)。
媽媽有一個(gè)方法,叫做“做飯”。有一個(gè)事件,叫做“開(kāi)飯”。做完飯后,調用開(kāi)飯事件,發(fā)布開(kāi)飯消息。
爸爸和孩子分別有一個(gè)方法,叫做“吃飯”。
將爸爸和孩子的“吃飯”方法,注冊到媽媽的“開(kāi)飯”事件。也就是,訂閱媽媽的開(kāi)飯消息。讓媽媽做完飯開(kāi)飯時(shí),發(fā)布吃飯消息時(shí),告訴爸爸和孩子一聲。
這種機制就是C#中的,訂閱發(fā)布。下面我們用代碼實(shí)現:
class Program { public static void Main(string[] args) { //實(shí)例化對象 Mom mom = new Mom(); Dad dad = new Dad(); Child child = new Child(); //將爸爸和孩子的Eat方法注冊到媽媽的Eat事件 //訂閱媽媽開(kāi)飯的消息 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事件,用于發(fā)布吃飯消息 public event Action Eat; public void Cook() { Console.WriteLine("媽媽 : 飯好了"); //飯好了,發(fā)布吃飯消息 Eat?.Invoke(); } } public class Dad { public void Eat() { //爸爸去吃飯 Console.WriteLine("爸爸 : 吃飯了。"); } } public class Child { public void Eat() { //熊孩子LOL呢,打完再吃 Console.WriteLine("孩子 : 打完這局再吃。"); } }運行結果:
當爺爺奶奶來(lái)做客了怎么辦呢?和爸爸孩子一樣,寫(xiě)個(gè)Eat方法,同樣注冊到媽媽的開(kāi)飯事件就好了。
?. 解釋?zhuān)?span style="color: rgb(0, 0, 0);font-family: "PingFang SC", "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;font-size: 14px;text-align: left;background-color: rgb(238, 238, 238);">如果前面的Eat不為空,則執行后面的Invoke
聯(lián)系客服