標籤:
委託事件的詳細使用
一、無參數,無返回的委託事件
委託事件類別、事件的發生源
1 public class Test 2 { 3 // …. 4 public delegate void TestHandler();//無參數,無返回委託 5 public event TestHandler TestEvent;//事件 6 public void OnTestHandler()//調用 7 { 8 if(TestEvent != null) //不等於null 說明該事件已經註冊有函數 9 {10 this.TestEvent();11 }12 }13 }
調用觸發事件方法(這裡把註冊和調用寫在一起,實際可以把註冊寫在另外的類)
1 class Program 2 { 3 static void Main(string[] args) 4 { 5 Test model = new Test();//實列 6 model.TestEvent += model_TestEvent;//為model 註冊TestEvent事件的執行方法 7 model.OnTestHandler();//調用引發事件 8 } 9 static void model_TestEvent()//事件執行方法,該方法樣式要與委託一致(參數,傳回值)10 {11 Console.WriteLine("這是最簡單的事件");12 }13 }
執行效果
補充1、
1 model.TestEvent += model_TestEvent;//為model 註冊TestEvent事件的執行方法,符合TestHandler委託樣式(參數,傳回值)的方法都可以進行註冊,可註冊多個函數,按順序執行。如改為 2 model.TestEvent += model_TestEvent1; 3 //model.TestEvent += new Test.TestHandler(model_TestEvent1);也可以這樣寫 4 model.TestEvent += model_TestEvent2; 5 static void model_TestEvent1() 6 { 7 Console.WriteLine("這是事件的函數1"); 8 }//可設定斷點看執行順序 9 static void model_TestEvent2()10 {11 Console.WriteLine("這是事件的函數2");12 }
執行效果
補充2、
Main(string[] args)方法中我們進行了註冊和調用,像觀察者模式使用,就會把註冊和調用進行分開。
註冊類,也就是所謂的訂閱類。該類也可以寫成介面,給不同業務的監聽者用來繼承擴張,這裡所有監聽者都執行model_TestEvent()函數。
1 public class Listeners 2 { 3 //註冊 4 public void registerEvent(Test model) 5 { 6 model.TestEvent += newTest.TestHandler(model_TestEvent); 7 } 8 //登出 9 public void nullifyEvent(Test model)10 {11 model.TestEvent -= newTest.TestHandler(model_TestEvent);12 }13 public virtual void model_TestEvent()14 {15 Console.WriteLine("這是所有監聽者要執行的函數");16 }17 }
這裡原來是註冊事件,現在改為執行個體,註冊監聽者。。
1 static void Main(string[] args) 2 { 3 Test model = new Test(); 4 //可以執行個體註冊多個監聽者 5 Listeners listener1 = new Listeners(); 6 Listeners listener2 = new Listeners(); 7 listener1.registerEvent(model); 8 listener2.registerEvent(model); 9 10 model.OnTestHandler(); //事件觸發後,會向所有註冊的監聽者發送,所有監聽者執行函數model_TestEvent11 }
執行效果
二、帶參數、傳回值的委託事件
首先定義事件的參數,這是自訂事件傳入的參數,從Eventargs繼承,也可直接用Eventargs,這裡為了簡單就只給了個string欄位,利用建構函式賦值。
1 public class TestEventArgs : EventArgs2 {3 public string parameters;4 public TestEventArgs(string par)5 {6 parameters = par;7 }8 }
委託事件類別
1 public class Test 2 { 3 public delegate string TestHandler(object sender, TestEventArgs tea);//帶參數,帶返回的委託 4 public event TestHandler TestEvent; //定義事件 5 public string OnTestEvent(TestEventArgs tea)//調用 6 { 7 if (TestEvent != null) 8 { 9 return TestEvent(this,tea);10 }11 return null;12 }13 }
註冊觸發
1 static void Main(string[] args) 2 { 3 Test model = new Test(); 4 model.TestEvent += model_TestEvent;//註冊事件 5 TestEventArgs tea = new TestEventArgs("test");//事件傳入參數 6 string result= model.OnTestEvent(tea) ;//事件觸發,得到結果 7 Console.WriteLine(result); 8 } 9 static string model_TestEvent(object sender, TestEventArgs tea)10 {11 return "傳入的參數是:" +tea.parameters ;12 }
補充1、
這裡註冊和觸發同樣可以分開,前面的註冊類中把model_TestEvent改為
1 public virtual string model_TestEvent(objectsender,TestEventArgs tea)//事件執行函數 2 { 3 return "傳入的參數是:" +tea.parameters; 4 } 5 class Program 6 { 7 static void Main(string[] args) 8 { 9 Test model = new Test();//執行個體10 Listeners listener = new Listeners();//執行個體監聽11 listener.registerEvent(model);//註冊12 TestEventArgs tea = new TestEventArgs("test"); //事件參數13 string result= model.OnTestEvent(tea);14 Console.WriteLine(result);15 }16 }
補充2、
事件參數類型也可以封裝,放在Test類內(OnTestEvent改為privte)。在Test類內加多
1 public string InitEvent(string par) 2 { 3 TestEventArgs tea = new TestEventArgs(par); 4 return OnTestEvent(tea); 5 } 6 Main就可以改為 7 static void Main(string[] args) 8 { 9 Test model = new Test();10 Listeners listener = new Listeners();11 listener.registerEvent(model);//監聽者註冊到Test.這裡如果很多不同業務的監聽者的話,如何返回所有監聽者處理完的資訊。修改Listeners類?(單例,管理者類)。12 string result = model.InitEvent("test");13 Console.WriteLine(result);14 }
完畢!多多指教。
關於c#的事件如何使用