平日裡做開發,在對一個按鈕點擊後的邏輯進行編碼時,我們得助於VS強大的功能,只要雙擊按鈕,在代碼中就會自動產生時間方法,然後我們只要在產生方法如:
privatevoid button1_Click(object sender, EventArgs e)
{
//TO DO
}
我們只要在TO DO 這裡寫好自己的邏輯即可。相信大多人也會用button1.Click+=new EventHandle(button1_Click)來給按鈕綁定事件方法。
現在我想自己寫一個Demo來類比這個過程,並且希望能夠加深對按鈕事件觸發的理解,順便也熟悉.net的事件模型。
代碼
using System;
using System.Collections.Generic;
using System.Text;
namespace EventDemo
{
///<summary>
/// 事件委託
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
publicdelegatevoid EventHandle(object sender, EventArgs e);
class Program
{
staticvoid Main(string[] args)
{
Button btn =new Button();
btn.Click +=new EventHandle(btn_Click);
Trigger(btn,EventArgs.Empty);//相當於滑鼠點擊觸發
Console.Read();
}
staticvoid btn_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
btn.Text ="我被點擊了";
Console.WriteLine(btn.Text);
}
///<summary>
/// 使用者單擊了表單中的按鈕後,Windows就會給按鈕訊息處理常式(WndPro)發送一個WM_MOUSECLICK訊息
///</summary>
///<param name="btn"></param>
///<param name="e"></param>
staticvoid Trigger(Button btn, EventArgs e)
{
btn.OnClick(e);
}
}
///<summary>
/// 類比Button
///</summary>
publicclass Button
{
privatestring txt;
publicstring Text
{
get { return txt; }
set { txt = value; }
}
publicevent EventHandle Click;//定義按鈕點擊時間
///<summary>
/// 事件執行方法
///</summary>
///<param name="sender"></param>
///<param name="e"></param>
void ActionEvent(object sender, EventArgs e)
{
if (Click ==null)
Click +=new EventHandle(Err_ActionEvent);
Click(sender, e);//這一部執行了Program中的btn_Click方法
}
void Err_ActionEvent(object sender, EventArgs e)
{
thrownew Exception("The method or operation is not implemented.");
}
publicvoid OnClick(EventArgs e)
{
ActionEvent(this, e);
}
}
}
以上是類比我們點擊滑鼠,然後執行事件函數的整個過程。
使用者單擊了表單中的按鈕後,Windows就會給按鈕訊息處理常式(WndPro)發送一個WM_MOUSECLICK訊息,對於.NET開發人員來說,就是按鈕的OnClick事件。
從客戶的角度討論事件:
事件接收器是指在發生某些事情時被通知的任何應用程式、對象或組件(在上面的Demo中可以理解為Button類的執行個體btn)。有事件接收器就有事件發送器。發送器的作用就是引發事件。發送器可以是應用程式中的另一個對象或者程式集(在上面的Demo中可以理解為程式集中的program引發事件),實際在系統事件中,例如按一下滑鼠或鍵盤按鍵,發送器就是.NET運行庫。注意,事件的發送器並不知道接收器是誰。這就使得事件非常有用。
現在,在事件接收器的某個地方有一個方法(在Demo中位OnClick),它負責處理事件。在每次發生登入的事件時執行事件處理常式(btn_Click)。此時就要用到委託了。由於發送器對接收器一無所知,所以無法設定兩者之間的參考型別,而是使用委託作為中介,發送器定義接收器要使用的委託,接受器將事件處理常式註冊到事件中,接受事件處理常式的過程成為封裝事件。
[參考:紅皮書第四版C#進階編程]