摘要:[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# 程式設計手冊)
- 事件範例
三小俠 小弟獻醜,歡迎指教


