摘要:[C#] 事件
Introduction
事件本身代表某種動作被執行,例如 button 被使用者按下,textbox 輸入文字..等
事件由類別所產生,其他物件或方法處理器因此被通知處理所觸發的事件,而其間的
關聯則透過委派物件來完成。
撰寫事件處理程式步驟如下:
- 宣告委派型別
- 定義 System.EventArgs 類別的衍生類別,儲存事件相關資訊
- 使用關鍵字 Event 宣告事件
- 定義事件處理程式之方法成員
- 使用委派物件封裝方法成員
- 引用委派方法處理觸發事件
其中建立事件的語法:
- event delegateName eventObject
event : 關鍵字
eventObject : 事件變數
delegateName : 支援此事件的委派名稱
Example
sample1
非標準版本
using System; //宣告一個委派型別:無回傳值,無任何參數。 delegate void DlgDoCalcDelegate() ; class calc { //宣告一個由 DlgDoCalcDelegate 委派所支援的事件 public event DlgDoCalcDelegate evtDoCalc; //定義觸發此事件的方法 public void DoCalc() { evtDoCalc(); } } class EventsHandler { //定義事件處理程式方法成員 private void DoAdd() { AddMethod() ; } private void AddMethod() { long lngFirstValue ; long lngSecondValue ; long lngSum ; Console.WriteLine ("請輸入第一個進行運算數值 :") ; lngFirstValue = long.Parse(Console.ReadLine()) ; Console.WriteLine ("請輸入第二個進行運算數值 :") ; lngSecondValue = long.Parse(Console.ReadLine()) ; lngSum = lngFirstValue + lngSecondValue; Console.WriteLine ("{0} 與 {1} 的加總等於 {2} " , lngFirstValue,lngSecondValue,lngSum) ; } static void Main() { EventsHandler myEventsHandler = new EventsHandler() ; calc mycalc = new calc() ; //將 DoAdd 方法於 evtDoCalc 事件中註冊 mycalc.evtDoCalc += new DlgDoCalcDelegate(myEventsHandler.DoAdd) ; Console.WriteLine ("觸發加法運算事件 …") ; //觸發事件。 mycalc.DoCalc() ; Console.Read() ; } }
執行結果
sample2
上面範例所示,我可以自訂任何方法支援觸發事件,然而,這不是最好的,
最好是符合 .net 事件處理方法的準則。以下我們觀察表單事件。
public Form1() { InitializeComponent(); //訂閱表單 Click 事件 this.Click += new EventHandler(Form1_Click); } //當表單事件被觸發後,會執行這個 Method void Form1_Click(object sender, EventArgs e) { //Do Something }
其中
sender : 代表觸發此事件的來源物件
e : 則包含了事件相關資訊的 EventArgs 類別物件,是其他事件類別的基底類別
reference :http://msdn.microsoft.com/zh-tw/library/ms229011%28VS.80%29.aspx
標準版本
using System; //定義 SpeedCheckEventArgs 繼承 EventArgs public class SpeedCheckEventArgs : EventArgs { //撰寫該事件相關資訊 private long speed; public SpeedCheckEventArgs(long speed) { this.speed = speed; } public long getSpeed { get { return speed; } } public string WarningMessage { get { return ("警告 : 行車超過速限 !!"); } } } //定義委派型別,沒有回傳值,並且需要兩個參數傳入 public delegate void SpeedCheckHandler(object sender, SpeedCheckEventArgs e); public class CheckSpeed { //定義符合 SpeedCheckHandler 委派的事件 public event SpeedCheckHandler myEvent; public void CheckSpeedLimit(long speed) { if (speed > 60) { //建立 SpeedCheckEventArgs 物件。 SpeedCheckEventArgs speedsArgs = new SpeedCheckEventArgs(speed); //觸發事件,傳入來源物件與事件物件。 myEvent(this, speedsArgs); } else { Console.WriteLine("您目前的速度正常"); } } } public class DoSomeThing { //定義 SlowDown 方法,傳入兩個參數,其中 e 為 SpeedCheckEventArgs 型別。 public void SlowDown(object sender, SpeedCheckEventArgs e) { Console.WriteLine (e.WarningMessage); Console.WriteLine("您目前車速 {0} 已超速,請踩下煞車,降低速度,避免危險 !!", e.getSpeed); Console.WriteLine ("正常行車速度請降至 60 Km/hr 以下 !!"); } } //主程式 public class Events { static void Main() { long speed; CheckSpeed myCheckSpeed = new CheckSpeed(); DoSomeThing myDoSomeThing = new DoSomeThing(); Console.Write("目前行車速度 : "); //取得使用者輸入數字 speed = long.Parse(Console.ReadLine()); Console.WriteLine(""); //訂閱事件。 myCheckSpeed.myEvent += new SpeedCheckHandler(myDoSomeThing.SlowDown); //檢查車速 myCheckSpeed.CheckSpeedLimit(speed); Console.ReadLine(); } }
執行結果
sample3
若是事件處理過程,不需使用 EventArg 引數傳遞事件所包含的資訊,可以考慮直接使用 EventHandler 這個
.net 預設的委派型別。
//定義一個計算類別
class calc {
//建立一個內鍵事件
public event EventHandler evtDoCalc;
//觸發事件
public void DoCalc() {
evtDoCalc(this, EventArgs.Empty);
}
}
//主程式
class Program {
static void Main(string[] args) {
Program myEventsHandler = new Program();
calc mycalc = new calc();
//繫結事件
mycalc.evtDoCalc += new EventHandler(myEventsHandler.DoAdd);
Console.WriteLine("觸發加法運算事件…");
//開始做計算
mycalc.DoCalc();
Console.Read();
}
private void DoAdd(object o, EventArgs e) {
Console.WriteLine("觸發事件的來源物件 : {0} \n", o.ToString());
AddMethod();
}
//加法函式
private void AddMethod() {
long lngFirstValue;
long lngSecondValue;
long lngSum;
Console.WriteLine("請輸入第一個進行運算數值 :");
lngFirstValue = long.Parse(Console.ReadLine());
Console.WriteLine("請輸入第二個進行運算數值 :");
lngSecondValue = long.Parse(Console.ReadLine());
lngSum = lngFirstValue + lngSecondValue;
Console.WriteLine
("{0} 與 {1} 的加總等於 {2} ", lngFirstValue, lngSecondValue, lngSum);
}
}
}
執行結果
sample4
多重事件
//定義委派型別 delegate void MultiCastDel(int intx, int inty); //加法類別 class AddCalc { public void DoAdd(int intx, int inty) { int intResult; intResult = intx + inty; Console.WriteLine("物件 AddCalc 對兩個整數 {0},{1} 作加法運算 !!", intx, inty); Console.WriteLine("執行運算結果等於 {0} \n", intResult); } } //減法類別 class SubCalc { public void DoSub(int intx, int inty) { int intResult; intResult = intx - inty; Console.WriteLine("物件 SubCalc 對兩個整數 {0},{1} 作減法運算 !!" , intx, inty); Console.WriteLine("執行運算結果等於 {0} \n", intResult); } } //乘法類別 class MultiCalc { public void DoMul(int intx, int inty) { int intResult; intResult = intx * inty; Console.WriteLine("物件 MultiCalc 對兩個整數 {0},{1} 作乘法運算 !!", intx, inty); Console.WriteLine("執行運算結果等於 {0} \n", intResult); } } //除法類別 class DivCalc { public void DoDiv(int intx, int inty) { if (inty == 0) { Console.WriteLine("除數為 0 無法作除法運算 !!"); } else { int intResult; intResult = intx / inty; Console.WriteLine("物件 DivCalc 對兩個整數 {0},{1} 作除法運算 !!", intx, inty); Console.WriteLine("執行運算結果等於 {0} \n", intResult); } } } //事件類別 class MultiEvent { int x; int y; public int px { set { x = value; } } public int py { set { y = value; } } //建立事件並且支援 MultiCastDel 委派 public event MultiCastDel DoEvent; public void OnDoEvent() { DoEvent(x, y); } } //主程式 class MultiCastEvent { static void Main() { AddCalc myAddCalc = new AddCalc(); SubCalc mySubCalc = new SubCalc(); MultiCalc myMultiCalc = new MultiCalc(); DivCalc myDivCalc = new DivCalc(); MultiEvent myMultiEvent = new MultiEvent(); myMultiEvent.px = 100; myMultiEvent.py = 100; myMultiEvent.DoEvent += new MultiCastDel(myAddCalc.DoAdd); myMultiEvent.DoEvent += new MultiCastDel(mySubCalc.DoSub); myMultiEvent.DoEvent += new MultiCastDel(myMultiCalc.DoMul); myMultiEvent.DoEvent += new MultiCastDel(myDivCalc.DoDiv); myMultiEvent.OnDoEvent(); Console.ReadLine(); } }
執行結果
- delegate (C# 參考)
- http://www.dotblogs.com.tw/atowngit/archive/2009/12/07/12311.aspx
- event (C# 參考)
- HOW TO:訂閱及取消訂閱事件 (C# 程式設計手冊)
- EventHandler 委派
- EventArgs 類別
- HOW TO:在衍生類別中引發基底類別事件 (C# 程式設計手冊)
- HOW TO:發行符合 .NET Framework 方針的事件 (C# 程式設計手冊)
- 事件設計
- HOW TO:實作介面事件 (C# 程式設計手冊)
- HOW TO:使用字典儲存事件執行個體 (C# 程式設計手冊)
- 事件範例
三小俠 小弟獻醜,歡迎指教