1.事件原理:
在說明事件的原理之前,我們先來做一個例子,如下:
1、啟動VS,建立一個winform應用程式,在form視窗中,我們建立一個按鈕,當點擊這個按鈕時,彈出訊息"you clicked me!"。
2、關於winform我們在以後會詳細講解。
3、我們雙擊按鈕後,在button1的click事件中的代碼如下: private void button1_Click(object sender, EventArgs e)
{ MessageBox.Show("you clicked me!"); } 這是一個完整的私人方法,參數為object sender和EventArgs e。
解釋: Object sender與 EventArgs e
(1)第一個參數sender是object基類,它表示了button1類本身,可以經過顯式轉換為button1類. (Button)sender
(2)EventArgs是包含事件數目據的類的基類,用於傳遞事件的細節,EventArgs是所有其它事件類別的基類。
把方法和事件聯絡起來:
(1) 我們通過程式介面看到,代碼如下: this.button1.Click += new System.EventHandler(this.button1_Click);
(2)this表示類本身(即form)而button1是它的一個控制項,Click 是button預定義的一個標準事件
(3)通過 += 將 一個System.EventHandler(this.button1_Click)的方法賦給了click事件。
System.EventHandler
(1)System.EventHandler 就是一個系統預定義的委託。
(2)該委託將事件與事件處理常式串連。
(3)委託是一個定義簽名的類型,即方法的傳回值類型和參數清單類型。
(4)系統的委託聲明如下 public delegate void EventHandler( object sender , EventArgs e ) 它定義了一個函數(方法)簽名的方式。
(5)private void button1_Click(object sender, EventArgs e) 滿足此簽名方式: 一、沒有傳回值 二、傳入參數
2.委託
(1)委託是一個類.
(2)它包含對方法的引用
(3)協助決定在運行時調用哪個方法
(4)步驟 –
1. 定義委託
2. 執行個體化委託
3. 使用委託
(5)如上面的new System.EventHandler(this.button1_Click);
1 1-->委託執行個體化:
2 //定義委託
3 public delegate int CallFun(int a, int b);
4 class MathsOperations
5 {
6 public int MulFun(int a, int b)
7 {
8 return a * b;
9 }
10 public int DivFun(int a, int b)
11 {
12 return a / b;
13 }
14 }
15 //執行個體化委託1(乘法)
16 CallFun DelegateObj1=new CallFun(MathsOprations.MulFun);
17 //執行個體化委託2(除法)
18 CallFun DelegateObj2 = new CallFun(MathsOprations.DivFun);
19
20 2-->委託使用:
21 //定義委託
22 public delegate int CallFun(int a, int b);
23 class MathsOperations
24 {
25 public int MulFun(int a, int b)
26 {
27 return a * b;
28 }
29 public int DivFun(int a, int b)
30 {
31 return a / b;
32 }
33 }
34
35 //執行個體化委託1(乘法)
36 CallFun DelegateObj1=new CallFun(MathsOprations.MulFun);
37 //使用委託
38 Console.WriteLine(DelegateObj1(2, 4));
39 //執行個體化委託2(除法)
40 CallFun DelegateObj2 = new CallFun(MathsOprations.DivFun);
41 //使用委託
42 Console.WriteLine(DelegateObj2(4, 2));
43 Console.ReadLine();
44
3.多播委託:
一個委託中可有多個方法
Delegate string delegateTest(string s);
delegateTest dt = new delegateTest(f1)
delegateTest dt2 = new delegateTest(f3)
dt = dt+dt2;
dt += new delegateTest(f2)
多播委託的使用:
//定義委託
public delegate void CallFun(int a, int b);
class MathsOprations
{
public static int result;
public static void MulFun(int i, int j)
{
result = i * j;
}
public static void DivFun(int i, int j)
{
result = result *(i / j);
}
}
//執行個體化委託
CallFun DelegateObj = new CallFun(MathsOprations.MulFun);
//多播委託
DelegateObj += new CallFun(MathsOprations.DivFun);
//調用多播委託
DelegateObj(9, 3);
System.Console.WriteLine("結果是:{0}", MathsOprations.result);
Console.ReadLine();
4.自訂事件
使用C#中的事件,對象可以將關於事件或已發生變化的語音總機其他對象把事件語音總機其他對象的對象稱為發布方註冊到事件的對象稱為訂戶
步驟
1.定義事件
2.給對象預訂該事件
3.通知事件的訂戶
我們可以通過自訂一個事件來進一步瞭解事件與委託的處理原理:
首先用一個死迴圈來類比監聽,我們把這個方法放入UserInputMonitor類中,當然這是一個公用類:
public void Run()
{
//finished永遠是false,所以永遠迴圈
bool finished = false;
do
{
if (Console.ReadLine() == "h")
{
//在這裡使用這個事件,格式就是委託的格式,事件發生人是本類,新執行個體化一個空事件類別傳遞參數。
OnUserRequest(this, new EventArgs());
}
} while (!finished);
}
自訂事件:
(1) 定義一個委託,可以放在類外,也可以放在類內,好像一個方法指標,包含指定的事件發生對象和描述事件本身的事件對象
public delegate void UserRequest(object sender, EventArgs e); 我們把它放在類外.
(2)自訂一個事件,不是系統本身的,如click!,要放在類內,而且必須指定委託
public event UserRequest OnUserRequest;
此代碼不斷的要求使用者輸入字元,如果輸入的結果是h,則觸發OnUserRequest事件,事件的觸發者是本身(this),事件細節無(沒有傳遞任何參數的EventArgs執行個體)。我們給這個類取名為UserInputMonitor。
我們還要定義一個Client類,在類中定義一個方法。
private void ShowMessage(object sender,EventArgs e)
{
Console.WriteLine("HaHa!!");
}
最後要做的是把這個方法和事件聯絡起來(訂閱事件),我們把它寫到Client類的建構函式裡。
public Client(UserInputMonitor m)
{
m.OnUserRequest+=new UserRequest(this.ShowMessage);
}
好了,我們下面來運行它了,
(1)首先得執行個體化UserInputMonitor類
UserInputMonitor monitor=new UserInputMonitor();
(2)下面建立用戶端的執行個體。
Client aa = new Client(monitor);
(3)最後讓monitor開始監聽事件。
monitor.run();
代碼如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 namespace ConsoleApplication1
5 {
6 //定義一個委託,可以放在類外,也可以放在類內,好像一個方法指標,包含指定的事件發生對象和描述事件本身的事件對象
7 public delegate void UserRequest(object sender, EventArgs e);
8
9 public class UserInputMonitor
10 {
11
12 //自訂一個事件,不是系統本身的,如click!,要放在類內,而且必須指定委託
13 public event UserRequest OnUserRequest;
14 //定義一個死迴圈
15 public void Run()
16 {
17 //finished永遠是false,所以永遠迴圈
18 bool finished = false;
19 do
20 {
21 if (Console.ReadLine() == "h")
22 {
23 //在這裡使用這個事件,格式就是委託的格式,事件發生人就是本類,新執行個體化一個空事件類別傳遞參數。
24 OnUserRequest(this, new EventArgs());
25 }
26 } while (!finished);
27 }
28 }
29 public class Client
30 {
31 public Client(UserInputMonitor m)
32 {
33 //訂閱者法
34 m.OnUserRequest+=new UserRequest(this.ShowMessage);
35 }
36
37 //定義一個方法
38 private void ShowMessage(object sender, EventArgs e)
39 {
40 Console.WriteLine("HaHa!!");
41 }
42 }
43
44 class Program
45 {
46 static void Main()
47 {
48 //執行個體化監聽對象
49 UserInputMonitor monitor = new UserInputMonitor();
50 //執行個體化用戶端,實現訂閱
51 Client aa = new Client(monitor);
52 //運行
53 monitor.Run();
54 }
55 }
56 }
57