在VB.Net當(dāng)中,事件的"關(guān)聯(lián)"是需要明顯標(biāo)志的,不像vb6當(dāng)中,聲明一個(gè)過程就是事件執(zhí)行過程了
從策劃到設(shè)計(jì)制作,每一步都追求做到細(xì)膩,制作可持續(xù)發(fā)展的企業(yè)網(wǎng)站。為客戶提供成都網(wǎng)站制作、做網(wǎng)站、網(wǎng)站策劃、網(wǎng)頁設(shè)計(jì)、域名注冊、雅安服務(wù)器托管、網(wǎng)絡(luò)營銷、VI設(shè)計(jì)、 網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造優(yōu)易品牌,攜手廣大客戶,共同發(fā)展進(jìn)步。
Handles用來靜態(tài)"關(guān)聯(lián)"一個(gè)或多個(gè)事件到一個(gè)過程
"關(guān)聯(lián)"時(shí),過程的簽名必須與事件的簽名相同(簽名的意義請查看相關(guān)文檔)
在VB.Net當(dāng)中,事件也是一個(gè)對象(VB.Net當(dāng)中一切皆為對象)
使用Handles時(shí)實(shí)際就相當(dāng)于創(chuàng)建了一個(gè)對委托的實(shí)現(xiàn)(委托的意義請查看相關(guān)文檔)
可以簡單的認(rèn)為,當(dāng)事件被觸發(fā)時(shí),被Handles"關(guān)聯(lián)"了的那些過程代碼將被執(zhí)行
而且,被"關(guān)聯(lián)"的過程可以任意起名,不需要與事件和對象的名稱相對應(yīng)
上述代碼如果去掉Handles 及其后面的內(nèi)容,它將是一個(gè)最普通不過的過程,與其它過程沒有兩樣,也不會(huì)有任何事件被觸發(fā)時(shí)去執(zhí)行這段代碼,正因?yàn)榧尤肓薍andles 及其后面的一堆事件,它才會(huì)因事件被觸發(fā)而被執(zhí)行
說得再簡單一點(diǎn): 當(dāng)PictureBox1.DoubleClick, PictureBox4.DoubleClick, PictureBox3.DoubleClick,PictureBox2.DoubleClick當(dāng)中的任何一個(gè)事件被觸發(fā)時(shí),上述這個(gè)過程的代碼都將被執(zhí)行
再說說參數(shù): sender表示觸發(fā)了此事件的對象,在這里就是PictureBox1/PictureBox2/PictureBox3/PictureBox4當(dāng)中的某一個(gè),利用它能知道到底是哪個(gè)對象觸發(fā)了此事件,e在這里沒有用處,利用不到什么,之所以有它,是因?yàn)镺bject/EventArgs是.Net事件的基本簽名方式,它的好處在你以后對.Net深入之后能體會(huì)到.
這些參數(shù)的值都是通過被觸發(fā)的事件傳遞過來的,可以簡單的認(rèn)為[事件調(diào)用了此過程并為參數(shù)賦了值]
所謂的委托(Delegate)實(shí)際上就是和C/C++里面的函數(shù)指針差不多,只是增強(qiáng)了類型檢查等其它健壯性方面的內(nèi)容。異步調(diào)用的回調(diào)函數(shù)有格式要求,所謂格式要求就是參數(shù)數(shù)量及類型順序的要求,具體是什么樣的你要看文檔了。一般.NET Framework里面都是AsyncCallBack。
所謂異步編程,就是說你要求做某樣事情,但是在完成這件事之前,我能接著做下一件事,而當(dāng)這件事情完成之后,能夠有一種機(jī)制通知我完成了。相反,在完成之前一直等待,直到完成了才能進(jìn)行下一步操作,叫做同步。一般來說,我們平常寫的程序都是“同步”,或者成為“順序執(zhí)行”更加貼切,而“異步”則可以說是“亂序執(zhí)行”的。
可以看到,同步的代碼非常好寫,因?yàn)槲覀兛梢灶A(yù)測執(zhí)行的順序和情況。而異步就不是很好寫了,因?yàn)闊o法得知完成的時(shí)候我正在做什么、做到什么程度。過去寫這些代碼是比較麻煩的,實(shí)現(xiàn)的辦法就是自己建立一個(gè)處理異步事物的線程,然后在這個(gè)線程和主線程之間建立聯(lián)系。而現(xiàn)在這個(gè)過程大部分已經(jīng)被系統(tǒng)封裝起來了,你只要調(diào)用BeginXXX,系統(tǒng)就會(huì)為你自動(dòng)建立一個(gè)新的線程處理這個(gè)事情,當(dāng)前線程不阻塞,可以馬上進(jìn)行下一項(xiàng)操作,于是就實(shí)現(xiàn)了“異步”了。但是從前面我講道的你就應(yīng)該知道,開始異步操作并沒有完事,還需要能夠得知操作完成,并能夠進(jìn)行相應(yīng)的處理。于是你在調(diào)用BeginXXX的時(shí)候就需要傳遞一個(gè)回調(diào)函數(shù),在.NET里是以委托的方式傳遞的。回調(diào)函數(shù)的意思就是“回過頭來調(diào)用你”,或者說A調(diào)用B并且傳遞函數(shù)C的地址,于是B在指定的情況下調(diào)用A指定的函數(shù)C?,F(xiàn)在就應(yīng)該明白這個(gè)回調(diào)函數(shù)在BeginXXX中的作用就是,當(dāng)你指定的事情做完之后將會(huì)調(diào)用這個(gè)回調(diào)函數(shù)。
在這個(gè)回調(diào)函數(shù)里面,我們就可以進(jìn)行一些后續(xù)的工作,例如接著進(jìn)行性質(zhì)相同的工作,或者相應(yīng)的處理。在這里,我們也許向知道剛才那件事情執(zhí)行的情況和結(jié)果,這個(gè)時(shí)候我們就可以通過EndXXX來獲得這些東西。說到這里,結(jié)合上面說到的AsyncCallBack以及隨便哪個(gè)BeginXXX,我們可能會(huì)對下列兩個(gè)東西感到困惑:
IAsyncResult
stateObject
首先說IAsyncResult,這個(gè)是一個(gè)接口,你在回調(diào)函數(shù)中通過參數(shù)獲得的對象具體是什么類型的一般我們不需要關(guān)心,我們只需要依照這個(gè)接口的定義進(jìn)行訪問就可以了。簡單點(diǎn)說,這個(gè)接口規(guī)定了順利完成異步操作所需信息的最小集合。一般來說,我們需要通過這個(gè)參數(shù)(ar)來識別異步操作。比如說,你在一瞬間發(fā)起一百個(gè)“從不同的網(wǎng)絡(luò)連接獲取數(shù)據(jù)”的異步請求,當(dāng)某一個(gè)請求被完成的時(shí)候,如何判斷是那個(gè)請求被完成呢?就是依靠回調(diào)函數(shù)的參數(shù)ar。實(shí)際上你一般是不需要參與判斷的,你只要將這個(gè)ar傳遞給EndXXX就可以了,EndXXX會(huì)根據(jù)這個(gè)ar自行判斷的。需要注意的是,這個(gè)ar就是你調(diào)用BeginXXX的時(shí)候的返回值,可以說是一個(gè)存根,如果你需要在完成操作前終止他,也可以通過將這個(gè)存根傳遞給EndXXX,EndXXX就會(huì)根據(jù)情況終止操作。(IAsyncResult里面的IsCompleted提供了是否已經(jīng)完成的判斷,EndXXX就是根據(jù)這個(gè)值決定是否有必要終止。當(dāng)然,你不需要關(guān)心他。)
接下來我們看看stateObject,這個(gè)東西被稱為狀態(tài)對象。于是大家就可能奇怪了:那個(gè)ar不也是狀態(tài)嗎?實(shí)際上stateObject是一個(gè)留給用戶使用的東西,BeginXXX/EndXXX根本就不使用。這個(gè)stateObject會(huì)被裝到ar的AsyncState里面,也就是說這個(gè)stateObject可以隨時(shí)通過訪問存根(BeginXXX的返回值)或者回調(diào)函數(shù)里的ar得到,你完全沒必要額外的保存到什么地方,更不需要費(fèi)神的去考慮如何和你的某個(gè)異步操作對應(yīng)起來。說了半天,這個(gè)東西有什么用呢?你想怎么用就怎么用唄,發(fā)揮一下你的想象力。比如說,你可以保存這是第幾次操作,或者在多個(gè)異步操作之間要同步的時(shí)候可以作為信號旗,再或者直接是操作這個(gè)異步操作的對象(x.BeginXXX的時(shí)候?qū)傳遞到stateObject參數(shù)上)。
第一種用法有點(diǎn)多余,第二種用法有點(diǎn)復(fù)雜,第三種我用得最多。因?yàn)槟愫芸赡茉趨f(xié)一個(gè)服務(wù)端,而服務(wù)段必須能夠響應(yīng)多個(gè)客戶端,這決定了必須用異步。同時(shí),對于多個(gè)客戶端必然有多個(gè)對象,例如網(wǎng)絡(luò)連接的時(shí)候可能是Socket。而實(shí)際上處理的方法或者協(xié)議是和具體哪個(gè)客戶端沒有關(guān)聯(lián)的,因此我們只需要一套處理程序就夠了。這個(gè)時(shí)候第三種用法就很有用處,我們完全可以把代碼寫成這樣:
Sub DataReceived(ByVal ar As IAsyncResult)
ar.AsyncState.EndReceive(ar)
ar.AsyncState.BeginReceive(... , ar.AsyncState)
End Sub
這樣就不需要額外的數(shù)據(jù)結(jié)構(gòu)去記錄有那些正在活動(dòng)的對象了。
TextBox組件(文本框組件)是一種常用的 也是比較容易掌握的組件 應(yīng)用程序主要使用它來接收使用者于輸入文字信息 在前面內(nèi)容中已經(jīng)或多或少的接觸到TextBox組件 本節(jié)就來詳細(xì)探討一下Visual 中TextBox組件的使用方法 一 TextBox組件 TextBox類 當(dāng)我們使用Visual Basic Net集成開發(fā)環(huán)境開發(fā)應(yīng)用程序時(shí) 在從【工具箱】的【W(wǎng)indows窗體】選項(xiàng)卡中向Form 的設(shè)計(jì)窗體拖入一個(gè)TextBox組件的后 我們可能并沒有感覺到即使時(shí)這樣一個(gè)簡單的操作 Visual Basic Net都做了很多幕后工作 主要工作和步驟如下 首先實(shí)例化System Windows Forms TextBox類 并根據(jù)拖動(dòng)到窗體的位置和形狀分別設(shè)定TextBox實(shí)例的各個(gè)屬性 我們看到的設(shè)計(jì)窗體 其實(shí)是Form 類的一個(gè)實(shí)例 而Form 類首先是從System Windows Forms Form類繼承而來 Form 類中的成員根據(jù)使用者往窗體中拖入的組件不同而不同 各個(gè)成員通過Add或AddRange方法加入到Form 中 這樣拖入的組件才能夠顯示在設(shè)計(jì)窗體上 以上這些都完全不同于以前Visual Basic 通過上述步驟 我們不難得到TextBox組件和TextBox類之間的關(guān)系 TextBox組件是命名空間System Windows Forms中的TextBox類的實(shí)例 在從【工具箱】的【W(wǎng)indows窗體】選項(xiàng)卡中拖入窗體的任一組件 都是 Net框架類庫—— Net Framework SDK中封裝的某一個(gè)類的實(shí)例 通過上述步驟也不難看出 Visual Basic Net的確才是真正的面向?qū)ο螅∣OP)的開發(fā)語言 二 TextBox類的成員 TextBox組件使用雖然比較簡單 但TextBox類的構(gòu)成成員卻是非常的豐富 在一般性的編程中 主要涉及到三類 屬性 方法和事件 表 表 和表 分別是TextBox類的常用屬性 方法和事件及其簡單說明 屬性 說明 AcceptsReturn 指示在多行TextBox組件中按ENTER鍵時(shí) 是在組件中創(chuàng)建一行新文本還是激活窗體的默認(rèn)按鈕 AcceptsTab 該值指示在多行文本框組件中按TAB鍵時(shí) 是否在組件中鍵入一個(gè)TAB字符 而不是按選項(xiàng)卡的順序?qū)⒔裹c(diǎn)移動(dòng)到下一個(gè)組件 AllowDrop 獲取或設(shè)置一個(gè)值 該值指示組件是否可以接受用戶拖放到它上面的數(shù)據(jù) Anchor 獲取或設(shè)置組件的哪些邊緣錨定到其容器邊緣 BackColor 獲取或設(shè)置組件的背景色 BackgroundImage 獲取或設(shè)置在組件中顯示的背景圖像 BorderStyle 獲取或設(shè)置文本框組件的邊框類型 Bottom 獲取組件的下邊緣與其容器的工作區(qū)的上邊緣之間的距離 CanFocus 獲取一個(gè)值 該值指示組件是否可以接收焦點(diǎn) CanSelect 獲取一個(gè)值 該值指示是否可以選中組件 CanUndo 獲取一個(gè)值 該值指示用戶在文本框組件中能否撤消前一操作 CharacterCasing 獲取或設(shè)置TextBox組件是否在字符鍵入時(shí)修改其大小寫格式 ContextMenu 獲取或設(shè)置與組件關(guān)聯(lián)的快捷菜單 Reated 獲取一個(gè)值 該值指示組件是否已經(jīng)創(chuàng)建 Cursor 獲取或設(shè)置當(dāng)鼠標(biāo)指針位于組件上時(shí)顯示的光標(biāo) DataBindings 為該組件獲取數(shù)據(jù)綁定 Dock 獲取或設(shè)置組件停靠到父容器的哪一個(gè)邊緣 Enabled 獲取或設(shè)置一個(gè)值 該值指示組件是否可以對用戶交互作出響應(yīng) Focused 獲取一個(gè)值 該值指示組件是否有輸入焦點(diǎn) Font 獲取或設(shè)置組件顯示的文字的字體 ForeColor 獲取或設(shè)置組件的前景色 MaxLength 獲取或設(shè)置用戶可以在文本框組件中最多鍵入的字符數(shù) Multiline TRUE/FALSE 該值指示它是否為多行文本框組件 PasswordChar 獲取或設(shè)置字符 該字符用于屏蔽單行 ScrollBars 獲取或設(shè)置哪些滾動(dòng)條應(yīng)出現(xiàn)在多行TextBox 組件中 Text 獲取或設(shè)置文本框中的當(dāng)前文本 TextAlign 設(shè)置文本框內(nèi)文本得對齊方式 TextLength 獲取組件中文本的長度 表 TextBox類的常用屬性及其說明 方法 說明 AppendText 向文本框的當(dāng)前文本追加文本 Clear 從文本框控件中清除所有文本 ClearUndo 從該文本框的撤消緩沖區(qū)中清除關(guān)于最近操作的信息 Copy 將文本框中的當(dāng)前選定內(nèi)容復(fù)制到剪貼板 Cut 將文本框中的當(dāng)前選定內(nèi)容移動(dòng)到剪貼板中 DoDragDrop 開始拖放操作 Focus 為控件設(shè)置輸入焦點(diǎn) GetChildAtPoint 檢索位于指定坐標(biāo)處的子控件 GetNextControl 按照子控件的Tab鍵順序向前或向后檢索下一個(gè)控件 Hide 對用戶隱藏控件 Paste 用剪貼板的內(nèi)容替換文本框中的當(dāng)前選定內(nèi)容 PointToClient 將指定屏幕點(diǎn)的位置計(jì)算成工作區(qū)坐標(biāo) PointToScreen 將指定工作區(qū)點(diǎn)的位置計(jì)算成屏幕坐標(biāo) ResetBindings 將DataBindings屬性重置為其默認(rèn)值 Select 選擇控件中的文本 SelectAll 選定文本框中的所有文本 SelectNextControl 激活下一個(gè)控件 Show 向用戶顯示控件 SuspendLayout 臨時(shí)掛起控件的布局邏輯 Undo 撤消文本框中的上一個(gè)編輯操作
表 TextBox類的常用方法及其說明
事件 說明 Click 在單擊文本框時(shí)發(fā)生 CursorChanged 當(dāng) Cursor 屬性的值更改時(shí)發(fā)生 DoubleClick 在雙擊控件時(shí)發(fā)生 DragDrop 在完成拖放操作時(shí)發(fā)生 DragEnter 在將對象拖入控件的邊界時(shí)發(fā)生 DragLeave 在將對象拖出控件的邊界時(shí)發(fā)生 DragOver 在將對象拖到控件的邊界上發(fā)生 EnabledChanged Enabled 屬性值更改后發(fā)生 Enter 進(jìn)入控件時(shí)發(fā)生 GiveFeedback 在執(zhí)行拖動(dòng)操作期間發(fā)生 GotFocus 在控件接收焦點(diǎn)時(shí)發(fā)生 KeyDown 在控件有焦點(diǎn)的情況下按下鍵時(shí)發(fā)生 KeyPress 在控件有焦點(diǎn)的情況下按下鍵時(shí)發(fā)生 KeyUp 在控件有焦點(diǎn)的情況下釋放鍵時(shí)發(fā)生 Leave 在輸入焦點(diǎn)離開控件時(shí)發(fā)生 LostFocus 當(dāng)控件失去焦點(diǎn)時(shí)發(fā)生 MouseDown 當(dāng)鼠標(biāo)指針位于控件上并按下鼠標(biāo)鍵時(shí)發(fā)生 MouseEnter 在鼠標(biāo)指針進(jìn)入控件時(shí)發(fā)生 MouseHover 在鼠標(biāo)指針懸停在控件上時(shí)發(fā)生 MouseLeave 在鼠標(biāo)指針離開控件時(shí)發(fā)生 MouseMove 在鼠標(biāo)指針移到控件上時(shí)發(fā)生 MouseUp 在鼠標(biāo)指針在控件上并釋放鼠標(biāo)鍵時(shí)發(fā)生 MouseWheel 在移動(dòng)鼠標(biāo)輪并且控件有焦點(diǎn)時(shí)發(fā)生 Move 在移動(dòng)控件時(shí)發(fā)生 Paint 在重繪控件時(shí)發(fā)生 Resize 在調(diào)整控件大小時(shí)發(fā)生
TextBox類的常用事件及其說明當(dāng)然TextBox類除了上述的屬性 方法和事件 還有很多屬性 方法和事件 和很多受保護(hù)的方法和受保護(hù)的屬性 由于它們使用的幾率較少和篇幅所限 就不能一一介紹了 感興趣的朋友可以參閱相關(guān)資料
三.掌握TextBox組件的基本用法 由于TextBox類的成員實(shí)在太豐富 一個(gè)示例要想介紹上述所有的方法 屬性和事件是不可能 在下面介紹的示例中 將突出介紹在Visual 集成開發(fā)環(huán)境下通過對設(shè)定不同的屬性值實(shí)現(xiàn)三種常見的TextBox組件式樣 以及TextBox組件的方法的調(diào)用方法和在Visual Basic Net集成開發(fā)環(huán)境中如何加入TextBox組件不同事件對應(yīng)的處理代碼 讓各位更加熟悉TextBox類和Visual Basic Net開發(fā)環(huán)境 下面是TextBox示例的具體實(shí)現(xiàn)步驟 啟動(dòng)Visual Studio Net 選擇菜單【文件】|【新建】|【項(xiàng)目】后 彈出【新建項(xiàng)目】對話框 將【項(xiàng)目類型】設(shè)置為【Visual Basic項(xiàng)目】 將【模板】設(shè)置為【W(wǎng)indows應(yīng)用程序】 在【名稱】文本框中輸入【TextBox組件】 在【位置】的文本框中輸入【E:\項(xiàng)目】 然后單擊【確定】按鈕 這樣在 E:\VS NET項(xiàng)目 目錄中就產(chǎn)生了名稱為 TextBox組件 的文件夾 并在里面創(chuàng)建了名稱為 TextBox組件 的項(xiàng)目文件 把Visual Studio Net的當(dāng)前窗口切換到【Form VB(設(shè)計(jì))】窗口 并從【工具箱】中的【W(wǎng)indows窗體組件】選項(xiàng)卡中往Form 窗體中拖入下列組件 并執(zhí)行相應(yīng)操作 三個(gè)Label組件 三個(gè)TextBox組件 分別為TextBox TextBox 和TextBox 按照表 中數(shù)值來設(shè)定設(shè)定組件的主要屬性 請注意TextBox組件中的屬性設(shè)定值
表 【TextBox組件】項(xiàng)目窗體中各組件的主要屬性設(shè)定數(shù)值表
按照表 各值設(shè)定后的TextBox組件三種常用的式樣也就產(chǎn)生了 具體如圖 所示
圖 程序設(shè)計(jì)時(shí)TextBox組件三種常見使用方法
這三種式樣就是單行的TextBox組件 多行的TextBox組件和用以輸入類似密碼數(shù)據(jù)的TextBox組件 為TextBox 組件添加事件和事件的處理代碼 此次添加的事件的名稱是Leave 當(dāng)TextBox 組件失去焦點(diǎn)時(shí)觸發(fā)此事件 添加TextBox 組件的其他事件也可仿照下面的處理方法 下面是利用Visual Basic Net在【TextBox組件】項(xiàng)目中添加TextBox 組件的Leave事件和添加Leave事件的處理代碼的具體步驟 首先把Visual Basic Net的當(dāng)前窗口切換到Form vb的代碼編輯界面 然后在如圖 所示的選擇框中選擇TextBox
圖 選擇TextBox組件
之后 在圖 所示的選擇框中選擇 Leave
圖 選取Leave事件
在選擇 Leave 之后 Visual Basic Net會(huì)自動(dòng)在Form vb中產(chǎn)生TextBox 的Leave事件 在Leave事件的事件處理代碼區(qū)添加下列代碼 下面代碼調(diào)用了TextBox 組件的 Clear 方法并且顯示一個(gè)TextBox 組件失去焦點(diǎn)的提示框
TextBox Clear ( ) 清除TextBox 組件的顯示內(nèi)容MsgBox ( 失去焦點(diǎn)! ) 彈出提示框
至此【TextBox組件】項(xiàng)目的全部工作就完成了 圖 是程序編譯后運(yùn)行界面
圖 【TextBox項(xiàng)目】的運(yùn)行界面
lishixinzhi/Article/program/net/201311/12721
Label1:?'建立標(biāo)簽,名為Label1。
GoTo?Label1??'跳轉(zhuǎn)到標(biāo)簽Label1所在位置。
注意不要陷入死循環(huán)!
run需要一個(gè)action方法。
這個(gè)方法用于用后臺進(jìn)程執(zhí)行占用大量CPU的工作,你的for代碼段應(yīng)該寫在里面。
我沒用過這個(gè),粗略看了一下資料,實(shí)際情況與他的實(shí)例不太一樣,Dim a As Task(of Boolean)=Await Doo(),直接提示錯(cuò)誤,正確用法是去掉await。
解決以上兩個(gè)問題,測試運(yùn)行通過。(一個(gè)文本框滾數(shù)字,另一個(gè)打字無壓力)
其實(shí)你的要求,不需要這么高級。多線程應(yīng)該可以。