淺析C#的事件處理和自定義事件一、了解C#中的預(yù)定義事件處理機(jī)制 在寫代碼前我們先來(lái)熟悉.net框架中和事件有關(guān)的類和委托,了解C#中預(yù)定義事件的處理。 EventArgs是包含事件數(shù)據(jù)的類的基類,用于傳遞事件的細(xì)節(jié)。 EventHandler是一個(gè)委托聲明如下 public delegate void EventHandler( object sender , EventArgs e ) 注意這里的參數(shù),前者是一個(gè)對(duì)象(其實(shí)這里傳遞的是對(duì)象的引用,如果是button1的click事件則sender就是button1),后面是包含事件數(shù)據(jù)的類的基類。 下面我們研究一下Button類看看其中的事件聲明(使用WinCV工具查看),以Click事件為例。 public event EventHandler Click; 這里定義了一個(gè)EventHandler類型的事件Click 前面的內(nèi)容都是C#在類庫(kù)中已經(jīng)為我們定義好了的。下面我們來(lái)看編程時(shí)產(chǎn)生的代碼。 private void button1_Click(object sender, System.EventArgs e) 這是我們和button1_click事件所對(duì)應(yīng)的方法。注意方法的參數(shù)符合委托中的簽名(既參數(shù)列表)。那我們?cè)趺窗堰@個(gè)方法和事件聯(lián)系起來(lái)呢,請(qǐng)看下面的代碼。 this.button1.Click += new System.EventHandler(this.button1_Click); 把this.button1_Click方法綁定到this.button1.Click事件。 下面我們研究一下C#事件處理的工作流程,首先系統(tǒng)會(huì)在為我們創(chuàng)建一個(gè)在后臺(tái)監(jiān)聽事件的對(duì)象(如果是 button1的事件那么監(jiān)聽事件的就是button1),這個(gè)對(duì)象用來(lái)產(chǎn)生事件,如果有某個(gè)用戶事件發(fā)生則產(chǎn)生對(duì)應(yīng)的應(yīng)用程序事件,然后執(zhí)行訂閱了事件的所有方法。 二、簡(jiǎn)單的自定義事件(1) 首先我們需要定義一個(gè)類來(lái)監(jiān)聽客戶端事件,這里我們監(jiān)聽鍵盤的輸入。 定義一個(gè)委托。 public delegate void UserRequest(object sender,EventArgs e); 前面的object用來(lái)傳遞事件的發(fā)生者,后面的EventArgs用來(lái)傳遞事件的細(xì)節(jié),現(xiàn)在暫時(shí)沒(méi)什么用處,一會(huì)后面的例子中將使用。 下面定義一個(gè)此委托類型類型的事件 public event UserRequest OnUserRequest; 下面我們來(lái)做一個(gè)死循環(huán) public void Run() 此代碼不斷的要求用戶輸入字符,如果輸入的結(jié)果是h,則觸發(fā)OnUserRequest事件,事件的觸發(fā)者是本身(this),事件細(xì)節(jié)無(wú)(沒(méi)有傳遞任何參數(shù)的EventArgs實(shí)例)。我們給這個(gè)類取名為UserInputMonitor。 下面我們要做的是定義客戶端的類 首先得實(shí)例化UserInputMonitor類 UserInputMonitor monitor=new UserInputMonitor(); 然后我們定義一個(gè)方法。 private void ShowMessage(object sender,EventArgs e) 最后要做的是把這個(gè)方法和事件聯(lián)系起來(lái)(訂閱事件),我們把它寫到庫(kù)戶端類的構(gòu)造函數(shù)里。 Client(UserInputMonitor m) //注意這種寫法是錯(cuò)誤的,因?yàn)槲惺庆o態(tài)的 下面創(chuàng)建客戶端的實(shí)例。 new Client(monitor); 對(duì)了,別忘了讓monitor開始監(jiān)聽事件。 monitor.run(); 大功告成,代碼如下: using System; 三、進(jìn)一步研究C#中的預(yù)定義事件處理機(jī)制 可能大家發(fā)現(xiàn)在C#中有些事件和前面的似乎不太一樣。例如 private void textBox1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) this.textBox1.KeyPress+=newSystem.Windows.Forms.KeyPressEventHandler(this.textBox1_KeyPress); 這里使用了KeyPressEventArgs而不是EventArgs作為參數(shù)。這里使用了KeyEventHandler委托,而不是EventHandler委托。 KeyPressEventArgs是EventArgs的派生類,而KeyEventHandler的聲明如下 public delegate void KeyEventHandler( object sender , KeyEventArgs e ); 是參數(shù)為KeyEventArgs的委托。那為什么KeyPress事件要這么做呢,我們可以從兩個(gè)類的構(gòu)造函數(shù)來(lái)找答案。 public EventArgs(); public KeyPressEventArgs(char keyChar); 這里的keyData是什么,是用來(lái)傳遞我們按下了哪個(gè)鍵的,哈。 我在KeyEventArgs中又發(fā)現(xiàn)了屬性 public char KeyChar { get; } 進(jìn)一步證明了我的理論。下面我們來(lái)做一個(gè)類似的例子來(lái)幫助理解。 四、簡(jiǎn)單的自定義事件(2) 拿我們上面做的例子來(lái)改。 我們也定義一個(gè)EventArgs(類似KeyEventArgs)取名MyEventArgs,定義一個(gè)構(gòu)造函數(shù)public MyEventArgs(char keyChar),同樣我們也設(shè)置相應(yīng)的屬性。代碼如下 using System; 因?yàn)楝F(xiàn)在要監(jiān)聽多個(gè)鍵了,我們得改寫監(jiān)聽器的類中的do...while部分。改寫委托,改寫客戶端傳遞的參數(shù)。好了最終代碼如下,好累 using System; |
|
來(lái)自: ShangShujie > 《.net》