“感興趣就好!”大李微微點點頭,然後問我道,“你知道 程序是怎麼知道哪些對象可以引發何種事件,以及怎麼樣把事件和事件處理程序 關聯起來?”
見到我迷茫的眼神,大李用鼠標點擊打開被region合 起來的“windows 窗體設計器生成的代碼”,指著中間的一句自動生 成的代碼:
friend withevents button1 as system.windows.forms.button
“當你在設計窗口往窗體上添加了一 個按鈕後,會自動在代碼中加入這句代碼,friend 關鍵字授予對一個或多個所聲 明的編程元素的友元訪問權限。那麼withevent是干什麼的?”
我立 刻在幫助中查找,有了:
withevents 關鍵字指示被聲明的對象變量引用 可以引發事件的類實例。
“明白了,”我也不能總傻聽著, “在聲明對象的時候用withevents來進行標識,再在事件處理程序中的過程 聲明結尾處使用 handles 關鍵字將就可以處理由使用 withevents 關鍵字聲明的 對象變量所引發的事件了。”
“沒錯,你看來我寫一段代碼, 使用的就是withevent-handles的方法來處理事件。類名為chenry吧,它內含一個 事件eventhr。”
module module1 public class chenry public event eventhr() ´ 聲明一個事件 sub causesomeevent() raiseevent eventhr() ´ 引發事件 end sub end class withevents obj as new chenry() ´模塊或類級別的聲明 sub obj_eventhr() handles obj.eventhr ´在handles之後聲明事 件 msgbox("事件處理器捕捉到了事件.") ´處理事件. end sub sub main() obj.causesomeevent() ´調用對象去引發事件 end sub end module
“你要注意的是怎麼樣通過raiseevent來引發事件, 另外一個很簡單的問題也需要注意的是,事件處理程序的命名一般是用‘對 象名_事件名’的方式。”大李邊寫程序邊指點說。
“事 件的聲明和引發是只能在一個層次內,還是可以在派生類裡引發基類的事件? ”我不由好奇地問。
“你開始學會思考了,”大李不知 道是不是在嘲笑我,“vb.net要求必須在聲明事件的范圍內引發事件。派生 類不能引發從基類繼承的事件,但是可以處理基類引發的事件。我們可以來看一 個示例。”大李馬上對剛寫的代碼進行了修改:
module module1 public class chenry public event eventhr() ´ 聲明一個事件 sub causesomeevent() raiseevent eventhr() ´ 引發事件 end sub end class public class class2 ‘從chenry派生而來的類 inherits chenry sub obj_eventhr() handles mybase.eventhr msgbox("事件處理器捕捉到了事件.") ´處 理事件. end sub end class withevents obj as new class2() ´模塊或類級別的聲明 sub main() obj.causesomeevent() ´調用對象去引發事件 end sub end module
“還記得我跟你說過mybase的意義了吧?(注:詳見 《構造與析構》一篇)我們可以添加 handles mybase.<event name> 語句 來聲明派生類中的事件處理程序。問一個基本的問題,你看obj是class2類的一個 實例對吧?但為什麼它也具有chenry類才有的causesomeevent方法?”大李 說得我眼球都快掉下來了。
“當然是因為class2是chenry類的派生 類,繼承了它的方法呗。”我神情極為沮喪。
“哈哈,別急呀 ,在vb.net中我們最常碰到的就是面向對象的問題。不斷回顧有好處,溫故而知 新!”大李最後的微笑對我倒不啻為一句忠告。要學好vb.net,我還真得好 好復習一下面向對象的內容。
大李話題一轉,淡淡地跟我說: “withevents 語句和 handles 子句提供了標准的陳述性指定事件處理程序 的方法。也就是如何把對象的事件和某一個事件處理程序進行關聯。withevents 所聲明對象引發的事件可以由任何過程用命名此事件的 handles 子句來處理。換 句話說,有handles子句標識的事件處理程序也只能處理由withevents聲明的對象 。雖然 handles 子句是關聯事件與事件處理程序的標准方法,它僅限於在編譯時 關聯事件與事件處理程序。還有一種方法可以允許在運行時動態地將事件與一個 或更多的事件處理程序連接或者斷開,而並不要求使用 withevents 來聲明對象 變量。”
“是嗎?”我一下子從沉思中驚醒過來,好奇 心又一次襲來。