C#事件(event)使用方法詳解
事件(event),這個(gè)詞兒對(duì)于初學(xué)者來(lái)說(shuō),往往總是顯得有些神秘,不易弄懂。而這些東西卻往往又是編程中常用且非常重要的東西。大家都知道windows消息處理機(jī)制的重要,其實(shí)C#事件就是基于windows消息處理機(jī)制的,只是封裝的更好,讓開發(fā)者無(wú)須知道底層的消息處理機(jī)制,就可以開發(fā)出強(qiáng)大的基于事件的應(yīng)用程序來(lái)。
先來(lái)看看事件編程有哪些好處。
在以往我們編寫這類程序中,往往采用等待機(jī)制,為了等待某件事情的發(fā)生,需要不斷地檢測(cè)某些判斷變量,而引入事件編程后,大大簡(jiǎn)化了這種過(guò)程:
- 使用事件,可以很方便地確定程序執(zhí)行順序。
- 當(dāng)事件驅(qū)動(dòng)程序等待事件時(shí),它不占用很多資源。事件驅(qū)動(dòng)程序與過(guò)程式程序最大的不同就在于,程序不再不停地檢查輸入設(shè)備,而是呆著不動(dòng),等待消息的到來(lái),每個(gè)輸入的消息會(huì)被排進(jìn)隊(duì)列,等待程序處理它。如果沒(méi)有消息在等待,則程序會(huì)把控制交回給操作系統(tǒng),以運(yùn)行其他程序。
- 事件簡(jiǎn)化了編程。操作系統(tǒng)只是簡(jiǎn)單地將消息傳送給對(duì)象,由對(duì)象的事件驅(qū)動(dòng)程序確定事件的處理方法。操作系統(tǒng)不必知道程序的內(nèi)部工作機(jī)制,只是需要知道如何與對(duì)象進(jìn)行對(duì)話,也就是如何傳遞消息。
有了這么多好處,看來(lái)我們的確有必要掌握它。俗話說(shuō):“難了不會(huì),會(huì)了不難”。就讓我們一步一步開始吧...
要講事件,必然要講到委托(delegate)。它們之間的關(guān)系可以通過(guò)一個(gè)淺顯的比方來(lái)說(shuō)明,這個(gè)比方可能不是十分恰當(dāng)。比如你要租一個(gè)房屋,這是一個(gè)事件,那么委托就是房屋租賃中介,當(dāng)你把租房子的消息告知中介后,中介就會(huì)產(chǎn)生出一套符合你要求的房屋租賃方案來(lái)。再由中介執(zhí)行這套方案,你便租得了這個(gè)房屋,即事件被處理了。當(dāng)然你也可以不通過(guò)中介,直接找房東,但如果沒(méi)有互聯(lián)網(wǎng)等工具,你如何得到誰(shuí)出租房屋的信息?話題扯遠(yuǎn)了。
委托(delegate)
委托可以理解成為函數(shù)指針,不同的是委托是面向?qū)ο螅沂穷愋?a href='http://m.jygsgssxh.com/dedecms_aq/' target='_blank'>安全的。關(guān)于委托的理解,可以參考我的另一篇文章《C#委托之個(gè)人理解》。
事件(event)
我們可以把事件編程簡(jiǎn)單地分成兩個(gè)部分:事件發(fā)生的類(書面上叫事件發(fā)生器)和事件接收處理的類。事件發(fā)生的類就是說(shuō)在這個(gè)類中觸發(fā)了一個(gè)事件,但這個(gè)類并不知道哪個(gè)個(gè)對(duì)象或方法將會(huì)加收到并處理它觸發(fā)的事件。所需要的是在發(fā)送方和接收方之間存在一個(gè)媒介。這個(gè)媒介在.NET Framework中就是委托(delegate)。在事件接收處理的類中,我們需要有一個(gè)處理事件的方法。好了,我們就按照這個(gè)順序來(lái)實(shí)現(xiàn)一個(gè)捕獲鍵盤按鍵的程序,來(lái)一步一步說(shuō)明如何編寫事件應(yīng)用程序。
1、首先創(chuàng)建一個(gè)自己的EventArgs類。
引自MSDN:
EventArgs是包含事件數(shù)據(jù)的類的基類,此類不包含事件數(shù)據(jù),在事件引發(fā)時(shí)不向事件處理程序傳遞狀態(tài)信息的事件會(huì)使用此類。如果事件處理程序需要狀態(tài)信息,則應(yīng)用程序必須從此類派生一個(gè)類來(lái)保存數(shù)據(jù)。
因?yàn)樵谖覀冩I盤按鍵事件中要包含按鍵信息,所以要派生一個(gè)KeyEventArgs類,來(lái)保存按鍵信息,好讓后面知道按了哪個(gè)鍵。
internal class KeyEventArgs : EventArgs
{
private char keychar;
public KeyEventArgs( char keychar ) : base()
{
this.keychar = keychar;
public char Keychar
{
get
{
return keychar;
}
}
}
2、再創(chuàng)建一個(gè)事件發(fā)生的類KeyInputMonitor,這個(gè)類用于監(jiān)控鍵盤按鍵的輸入并觸發(fā)一個(gè)事件:
internal class KeyInputMonitor
{
// 創(chuàng)建一個(gè)委托,返回類型為void,兩個(gè)參數(shù)
public delegate void KeyDownHandler( object sender, KeyEventArgs e );
// 將創(chuàng)建的委托和特定事件關(guān)聯(lián),在這里特定的事件為KeyDown
public void Run()
{
bool finished = false;
do
{
Console.WriteLine( "Input a char" );
string response = Console.ReadLine();
char responsechar = ( response == "" ) ? ' ' : char.ToUpper( response[0] );
switch( responsechar )
{
case 'X':
finished = true;
break;
default:
// 得到按鍵信息的參數(shù)
KeyEventArgs keyEventArgs = new KeyEventArgs( responsechar );
// 觸發(fā)事件
KeyDown( this, keyEventArgs );
break;
}
}
while( !finished );
}
}
這里注意KeyDown( this, KeyEventArgs );一句,這就是觸發(fā)事件的語(yǔ)句,并將事件交由KeyDownHandler這個(gè)委托來(lái)處理,委托指定事件處理方法去處理事件,這就是事件接收方的類的事情了。參數(shù)this是指觸發(fā)事件的對(duì)象就是本身這個(gè)對(duì)象,keyEventArgs包含了按鍵信息。
3、最后創(chuàng)建一個(gè)事件接收方的類,這個(gè)類先產(chǎn)生一個(gè)委托實(shí)例,再把這個(gè)委托實(shí)例添加到產(chǎn)生事件對(duì)象的事件列表中去,這個(gè)過(guò)程又叫訂閱事件。然后提供一個(gè)方法回顯按鍵信息。
internal class EventReceiver
{
public EventReceiver( KeyInputMonitor monitor )
{
// 產(chǎn)生一個(gè)委托實(shí)例并添加到KeyInputMonitor產(chǎn)生的事件列表中
monitor.KeyDown += new KeyInputMonitor.KeyDownHandler( this.OnKeyDown );
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
// 真正的事件處理函數(shù)
Console.WriteLine( "Capture key: {0}", e.Keychar );
}
}
4、看一下如何調(diào)用
public class MainEntryPoint
{
public static void Start()
{
// 實(shí)例化一個(gè)事件發(fā)送器
KeyInputMonitor monitor = new KeyInputMonitor();
// 實(shí)例化一個(gè)事件接收器
EventReceiver eventReceiver = new EventReceiver( monitor );
// 運(yùn)行
monitor.Run();
}
}
總結(jié):
C#中使用事件需要的步驟:
1.創(chuàng)建一個(gè)委托
2.將創(chuàng)建的委托與特定事件關(guān)聯(lián)(.Net類庫(kù)中的很多事件都是已經(jīng)定制好的,所以他們也就有相應(yīng)的一個(gè)委托,在編寫關(guān)聯(lián)事件處理程序--也就是當(dāng)有事件發(fā)生時(shí)我們要執(zhí)行的方法的時(shí)候我們需要和這個(gè)委托有相同的簽名)
3.編寫事件處理程序
4.利用編寫的事件處理程序生成一個(gè)委托實(shí)例
5.把這個(gè)委托實(shí)例添加到產(chǎn)生事件對(duì)象的事件列表中去,這個(gè)過(guò)程又叫訂閱事件
C#中事件產(chǎn)生和實(shí)現(xiàn)的流程:
1.定義A為產(chǎn)生事件的實(shí)例,a為A產(chǎn)生的一個(gè)事件
2.定義B為接收事件的實(shí)例,b為處理事件的方法
3.A由于用戶(程序編寫者或程序使用者)或者系統(tǒng)產(chǎn)生一個(gè)a事件(例如點(diǎn)擊一個(gè)Button,產(chǎn)生一個(gè)Click事件)
4.A通過(guò)事件列表中的委托對(duì)象將這個(gè)事件通知給B
5.B接到一個(gè)事件通知(實(shí)際是B.b利用委托來(lái)實(shí)現(xiàn)事件的接收)
6.調(diào)用B.b方法完成事件處理
public class A
{
public delegate void EventHandler(object sender);
public void Run()
{
Console.WriteLine("Trigger an event.");
a(this);
}
}
class B
{
public B(A a)
{
a.a += new A.EventHandler(this.b);
}
private void b(object sender)
{
Console.WriteLine("Received and handled an event." );
Console.Read();
}
}
上一篇:C# lambda表達(dá)式應(yīng)用如何找出元素在list中的索引
欄 目:C#教程
下一篇:C++通過(guò)Callback向C#傳遞數(shù)據(jù)的方法
本文標(biāo)題:C#事件(event)使用方法詳解
本文地址:http://m.jygsgssxh.com/a1/C_jiaocheng/5292.html
您可能感興趣的文章
- 01-10C#自定義事件監(jiān)聽實(shí)現(xiàn)方法
- 01-10C#3.0使用EventLog類寫Windows事件日志的方法
- 01-10c# ArrayList的使用方法小總結(jié)
- 01-10WinForm判斷關(guān)閉事件來(lái)源于用戶點(diǎn)擊右上角“關(guān)閉”按鈕的方法
- 01-10C#.Net ArrayList的使用方法
- 01-10C#中比較常用的DateTime結(jié)構(gòu)的使用方法
- 01-10結(jié)合Visual C#開發(fā)環(huán)境講解C#中事件的訂閱和取消訂閱
- 01-10結(jié)合.net框架在C#派生類中觸發(fā)基類事件及實(shí)現(xiàn)接口事件
- 01-10在C#使用字典存儲(chǔ)事件示例及實(shí)現(xiàn)自定義事件訪問(wèn)器
- 01-10C#委托與事件初探


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過(guò)反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻播放器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過(guò)重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什


