<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    飛艷小屋

    程序--人生--哲學___________________歡迎艷兒的加入

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      52 Posts :: 175 Stories :: 107 Comments :: 0 Trackbacks
    使用客戶端腳本
    使用客戶端腳本
    發布日期: 9/20/2004 | 更新日期: 9/20/2004

    Scott Mitchell

    4GuysFromRolla.com

    摘要:盡管 ASP.NET 在服務器上執行其大多數操作,但是某些操作在客戶端進行處理可能會更好。Scott Mitchell 說明了 ASP.NET 頁面和控件如何添加客戶端代碼。

    *
    本頁內容 簡介 簡介 創建基類作為添加客戶端腳本的基礎 創建基類作為添加客戶端腳本的基礎 從代碼隱藏類添加客戶端腳本 從代碼隱藏類添加客戶端腳本 根據對用戶操作的響應執行客戶端代碼 根據對用戶操作的響應執行客戶端代碼 實現常用客戶端功能 實現常用客戶端功能 小結 小結 相關書籍 相關書籍
    簡介

    當使用動態的、基于 Web 的腳本技術時,與傳統 ASP 或 PHP 類似,開發人員必須對客戶端和服務器間的邏輯、暫時和物理分隔有著敏銳的理解。例如,對于觸發服務器端代碼執行的用戶操作,使用傳統 ASP 的開發人員必須明確地使用戶的瀏覽器將請求返回到 Web 服務器。創建這樣的交互可能會輕易地占用大量開發時間,并且導致不易讀的代碼。

    Microsoft ASP.NET 通過使用 Web 窗體,有助于減輕將用戶事件綁定到特定服務器端代碼執行的負擔,這就模糊了客戶端和服務器間的界線。使用 ASP.NET 和最少的工作,開發人員就可以快速地創建如下的網頁,它具有大量的交互式用戶界面元素按鈕、下拉列表等,而這些都基于最終用戶的操作,可以選擇性地運行服務器端代碼。例如,利用 ASP.NET 添加下拉列表,只要選定的下拉列表項目更改則執行某些操作,您只需添加 DropDownList Web 控件、將其 AutoPostBack 屬性設置為 True,然后為該下拉列表創建一個 SelectedIndexChanged 事件處理程序。如果利用傳統的 ASP 完成上述任務,則會要求編寫許多復雜的 HTML、客戶端 JavaScript 和服務器端腳本代碼;利用 ASP.NET,則為您提供了必要的腳本代碼和服務器端事件模型。

    盡管在執行客戶端操作時,ASP.NET 中的 Web 窗體極大地簡化了運行服務器端腳本,但是,如果誤用這種功能可能會導致無法接受的性能。盡管 Web 窗體隱藏了所涉及的復雜性,每次需要執行服務器端代碼時,最終用戶的瀏覽器必須通過重新提交窗體,將請求返回到 Web 服務器。當提交窗體時,所有窗體字段(文本框、下拉列表和復選框等)必須同時返回它們的值。此外,頁面的視圖狀態也被返回到 Web 服務器。總而言之,每次回發網頁時,幾千字節的數據將需要潛在地發送回 Web 服務器。于是,經常回發可能很快就會導致 Web 應用程序不可使用,尤其是對于那些仍然使用撥號連接的用戶。通過將功能推到客戶端可以降低經常回發的需要。

    ASP.NET Web 窗體發出一個標題為 VIEWSTATE 的隱藏窗體字段,它包含 Web 窗體中 Web 控件已更改狀態的基于 64 位編碼的表示。根據出現的 Web 控件,視圖狀態的范圍可以從幾十字節到幾萬字節。要學習有關視圖狀態的更多知識,請查閱我的文章 Understanding ASP.NET View State

    利用傳統的 ASP,添加數據驅動、自定義客戶端腳本非常簡單,但并不是非常易讀。例如,要在傳統的 ASP 中顯示根據某個 ID 字段加載 URL 的彈出窗口,您可以使用 語法來插入 ID 字段的值,在適當的客戶端腳本中進行輸入。ASP.NET 允許您利用 Page 類中的各種方法,創建這種數據驅動的客戶端腳本。

    本文分析了向 ASP.NET 網頁添加客戶端腳本的技術。客戶端腳本是運行在訪問者瀏覽器中的腳本代碼,如其名字所示。我們將看到如何完成常見的客戶端任務,例如顯示警告、確認框和彈出窗口。(客戶端腳本窗體字段驗證的一個主要用途可能與 ASP.NET 主題有點不相關,因為驗證程序 Web 控件提供了隨取隨用的客戶端窗體驗證。)本文的重點在于插入客戶端腳本的服務器端類、方法和技術;我們不會詳細地分析實際的客戶端腳本,因為該信息涉及了圍繞 Web 的眾多其他文章和站點。

    創建基類作為添加客戶端腳本的基礎

    傳統的 ASP 和 ASP.NET 之間的主要差別之一在于各自技術的編程模型。ASP 頁面是原子的、程序上的腳本,解釋每個頁面的訪問。然而,ASP.NET 完全是面向對象的編程技術。所有 ASP.NET 網頁都是帶有屬性、方法和事件的類。所有網頁直接或間接地派生自 System.Web.UI 命名空間中的 Page 類,Page 類包含了 ASP.NET 網頁的基本功能。

    面向對象編程的概念之一就是繼承。繼承使您可以創建一個擴展其他類功能的新類。(如果類 B 繼承類 A,也可以說擴展了 A;類 A 被稱為基類。)當使用代碼隱藏模型來創建 ASP.NET 網頁時,可以非常清楚地看到代碼隱藏類繼承了 Page 類:

    Public Class WebForm1 Inherits System.Web.UI.Page ... End Class

    通過使您的代碼隱藏類繼承 Page 類,它自動接收在 Page 類中繼承的功能,例如 RequestResponseSessionViewState 對象以及常見事件,如 InitLoadRender 等等。我們將在本文中看到,如果您需要可用于所有 ASP.NET 網頁的某個常見功能,一種方法是創建派生自 Page 類并具有完成這些所需增強功能的其他方法和屬性的類。然后,要使 ASP.NET 網頁利用這些增強功能,我們只需更新頁面代碼隱藏類中的 Inherits 語句,以使用擴展 Page 類的類。

    在本文中,我們將創建一個名為 ClientSidePage 的類,它派生自 Page 類并提供額外的方法以協助執行常見的客戶端任務。通過讓代碼隱藏類繼承 ClientSidePage,而不是繼承 Page,添加腳本代碼將會像調用方法和傳送幾個參數那樣簡單。具體說來,該類包括用于下列用途的方法:

    ?

    顯示模式客戶端對話框。

    ?

    在頁面加載時將焦點設置到特定的窗體字段。

    ?

    使用模式確定對話框來確定用戶是否希望回發該窗體。

    ?

    顯示彈出窗口。

    在我們深入研究 ClientSidePage 類之前,首先讓我們分析一下 Page 類中的有關方法,以便將客戶端腳本插入到網頁中。在我們討論這些 Page 方法后,我們將開始利用 ClientSidePage 類擴展它們的功能,并且查看如何將所有內容結合在一起以及如何在 ASP.NET 網頁中使用擴展的類。

    從代碼隱藏類添加客戶端腳本

    所有 ASP.NET 網頁必須直接或間接地派生自 System.Web.UI 命名空間中的 Page 類。Page 類包含正常運行的網頁所要求的方法、屬性和事件的基本集合。在該類的眾多方法中,一些方法旨在將客戶端腳本插入到生成的 HTML 中。這些方法從代碼隱藏類調用,因此可以用于發出數據驅動的客戶端腳本。用于發出客戶端腳本的相關 Page 類方法如下所示。

    該基類派生自 System.Web.UI.Page 類,因此可以通過從代碼隱藏類直接調用 Page 類的公共方法來訪問它們。

    要訪問 Page 類的方法,您可以直接鍵入方法名,或者通過輸入 MyBase.(對于 Microsoft Visual Basic .NET)、this. (對于 C#)或者 Page.(對于 C# 或 Visual Basic .NET),利用 Microsoft Visual Studio .NET 中的 IntelliSense 來實現。如果使用 Visual Basic .NET 作為選擇的編程語言,請確保將 Visual Studio .NET 配置為不 隱藏高級成員,否則將無法看到這些客戶端腳本方法。(要顯示高級成員,請轉到 Tools | Options | TextEditor | Basic,然后清除 Hide advanced members 復選框。)

    RegisterClientScriptBlock(key, script)

    在 Web 窗體已呈現的 <form> 元素之后,在包含于 Web 窗體中的任意 Web 控件之前,RegisterClientScriptBlock 方法會添加一個客戶端腳本塊。key 輸入參數允許您指定與該腳本塊相關聯的唯一的密鑰,而 script 參數包括要發出的完整的腳本代碼。(這個 script 參數應該包括實際的 <script> 元素,同時還包括客戶端 JavaScript 或 Microsoft VBScript。)

    在通過 ASP.NET 網頁的代碼隱藏類發出客戶端腳本時,通常情況下,key 參數的值就不是非常重要了。簡單地選擇一個說明性的密鑰值。在通過自定義編譯的服務器控件插入客戶端腳本代碼時,key 參數就更加適用。編譯的控件有可能需要一組客戶端函數。一個頁面上服務器控件的多個實例可以共享這些公用客戶端腳本函數,因此對于整個頁面而言,這些函數只需要發出一次即可,不需要每個控件實例發送一次。例如,驗證控件利用客戶端代碼來增強用戶體驗。如果頁面上存在任意驗證控件,這種客戶端代碼就必須存在,但是如果存在多個驗證控件,那么全部控件都可以使用這個單個的共享函數的集合。

    通過為腳本塊提供一個密鑰,利用公用客戶端函數集合構建控件的控件開發人員可以檢查所要求的公用函數集合是否已經被頁面上控件的另一個實例添加。如果已添加,它不需要重新添加公用腳本。要檢查腳本塊是否已經使用相同的密鑰添加,請使用 IsClientScriptBlockRegistered(key) 方法,它將返回布爾值,表示帶有相同密鑰的腳本塊是否已經進行了注冊。需要注意的是可以在不首先檢查它是否注冊的情況下添加腳本塊。如果嘗試利用已經注冊的密鑰添加腳本塊,添加的腳本塊將被忽略,并且原來的腳本將保持分配到該密鑰。

    IsClientScriptBlockRegistered 方法在以下兩種情況下尤為有用。第一,當添加相似但又獨特的腳本塊時它很方便,您需要確保每個腳本塊都給予唯一的密鑰。本文稍后分析的代碼說明了“is registered”方法的實用性。第二個用途就是當構建需要某個公用腳本的控件時,尤其是如果特別的生成該腳本。通過使用 IsClientScriptBlockRegistered 方法,可以確保對頁面上服務器控件的所有腳本通用的腳本在每次頁面加載時只生成一次,而不是對頁面上的每個控件實例都生成一次。

    RegisterClientScriptBlock 方法對于添加客戶端腳本非常有用,該腳本不依賴于 Web 窗體內出現的任意窗體字段。該方法的常見使用就是顯示客戶端警告框。例如,設想您具有一個帶有一些 TextBox Web 控件和一個“Save”按鈕的網頁。TextBox 控件可能會具有來自數據庫的特殊值。設想該頁面允許用戶修改這些值并通過單擊“Save”按鈕提交他們所做的更改。當單擊“Save”時,網頁將會回發,并且會觸發按鈕的 Click 事件。您可以為更新數據庫的事件創建一個服務器端事件處理程序。要使用戶知道他們的更改已經保存,您可能希望顯示一個警告框“Your changes have been saved”。通過將以下代碼行添加到按鈕的 Click 事件處理程序中,可以實現這個任務:

    RegisterClientScriptBlock("showSaveMessage", _ "<script language=""JavaScript""> _ alert('Your changes have been saved.'); _ </script>")

    上述代碼將會在頁面的 <form> 內添加指定的腳本內容,但是在該窗體的內容前。當在用戶瀏覽器中生成頁面時,他們將會看到根據頁面加載顯示的客戶端警告框,如圖 1 所示。

    <form method="post" ...> <script language="JavaScript"> alert('Your changes have been saved.'); </script> ... </form>

    1. 客戶端 JavaScript 的結果

    上面示例中一個潛在地不需要的副作用就是,警告框將會在瀏覽器接收到 <form> 標記后立即顯示。在用戶單擊警告框的“OK”按鈕之前,瀏覽器將掛起網頁的呈現。這意味著用戶在單擊“OK”之前,將看到一個空白的瀏覽器頁面。如果希望在顯示警告框之前完全顯示該頁面,您可以使用 RegisterStartupScript 方法(我們將在下面進行討論),在 <form> 元素的結尾處插入 JavaScript。

    RegisterStartupScript(key, script)

    RegisterStartupScript 方法與 RegisterClientScriptBlock 方法非常相似。主要的區別在于發出客戶端腳本的位置。在 <form> 元素開始后,在窗體的內容前,記住用 RegisterClientScriptBlock 發出腳本。另一方面,RegisterStartupScript 在窗體的結尾 處、在所有窗體字段后,添加指定的腳本。使用 RegisterStartupScript 來放置與呈現的 HTML 元素交互的客戶端腳本。(稍后我將研究根據頁面加載將焦點設置到窗體字段的示例;要完成這個操作,您將要使用 RegisterStartupScript 方法。)

    RegisterClientScriptBlock 相似,由 RegisterStartupScript 添加的腳本塊需要一個唯一的密鑰值。同樣,該密鑰值主要由自定義控件開發人員使用。并不奇怪,還有一個 IsStartupScriptRegistered(key) 方法,它返回布爾值,表示帶有指定密鑰 的腳本塊是否已經進行了注冊。

    有關使用 RegisterStartupScriptRegisterClientScriptBlock 來創建自定義編譯的服務器控件的詳細信息,請閱讀我以前的文章: Injecting Client-Side Script from an ASP.NET Server Control.

    RegisterArrayDeclaration(arrayName, arrayValue)

    如果需要創建帶有某些設置值的客戶端 JavaScript Array 對象,請使用該方法向特定的數組添加值。例如,當使用 ASP.NET 網頁中的驗證控件時,就會構建 Array 對象 (Page_Validators),以包含對頁面上驗證控件集合的引用。當提交窗體時,就會枚舉該數組以檢查各種驗證控件是否有效。

    要將值 1、2 和 3 添加到名為 FavoriteNumbers 的客戶端 Array 對象,要使用以下服務器端代碼:

    RegisterArrayDeclaration("FavoriteNumbers", "1") RegisterArrayDeclaration("FavoriteNumbers", "2") RegisterArrayDeclaration("FavoriteNumbers", "3")

    這段代碼會發出以下客戶端腳本:

    <script language="javascript"> <!-- var FavoriteNumbers = new Array(1, 2, 3); // --> </script>

    請注意,被傳遞的每個數組值都必須是字符串;但是,呈現的客戶端腳本將 Array 對象的值設置為字符串的內容。也就是說,如果希望創建帶有字符串值“Scott”和“Jisun”的 Array,要使用以下代碼:

    RegisterArrayDeclaration("FavoriteFolks", "'Scott'") RegisterArrayDeclaration("FavoriteFolks ", "'Jisun'")

    請注意,第二個輸入參數是包含 'Scott' 和 'Jisun' 的字符串 - 文本由單撇號分隔。這會顯示以下客戶端腳本:

    <script language="javascript"> <!-- var FavoriteFolks = new Array('Scott', 'Jisun'); // --> </script>
    RegisterHiddenField(hiddenFieldName, hiddenFieldValue)

    在傳統的 ASP 中,通常需要將各種信息從一個頁面分發到另一個頁面。完成這個操作的常用方法就是使用隱藏窗體字段。(隱藏窗體字段是不顯示的窗體字段,但是它的值會根據窗體的提交而發送。創建隱藏窗體字段的語法是 。)在 ASP.NET 中,通過自定義隱藏窗體字段傳遞信息的需要會極大地減少,因為頁面中的控件狀態會自動保持。但是,如果您發現需要創建自定義隱藏窗體字段,可以通過 RegisterHiddenField 方法來完成。

    RegisterHiddenField 方法接受兩個輸入參數。隱藏字段的名稱和值。例如,要創建帶有名稱 foo 和值 bar 的隱藏窗體字段,請使用以下代碼:

    RegisterHiddenField("foo", "bar")

    這會在頁面的 <form> 元素中添加隱藏窗體字段,如下所示:

    <form name="_ctl0" method="post" action="test.aspx" id="_ctl0"> <input type="hidden" name="foo" value="bar" /> ... </form>
    理解客戶端元素是如何呈現的

    Page 類包含負責呈現在上面討論的方法中注冊的客戶端腳本的兩個 internal 方法:OnFormRenderOnFormPostRender。(標記為 internal 的方法只能被相同程序集中的其他類調用。因此,無法從 ASP.NET Web 應用程序中的代碼隱藏類調用 Pageinternal 方法。)這兩個方法都在 HtmlForm 類的 RenderChildren 方法中進行調用。位于 System.Web.UI.HtmlControls 命名空間中的 HtmlForm 類表示 Web 窗體;也就是說,ASP.NET 網頁中的服務器端窗體<form runat="server">...</form> 在頁面的實例化階段中作為 HtmlForm 類的實例加載。

    因為由 Page 類的眾多方法注冊的客戶端腳本是在 OnFormRenderOnFormPostRender 方法中呈現的,并且因為這些方法只能由 HtmlForm 類進行調用,所以通過這些方法以編程方式添加的客戶端腳本,只有在網頁包含 Web 窗體時才會呈現。也就是說,通過上面討論的任意方法以編程方式添加的任意腳本元素,在 ASP.NET 網頁包含服務器端窗體(<form runat="server">...</form>)時只會在頁面的最后標記中發出。

    通過首先添加開始 <form> 元素,會呈現 ASP.NET 網頁上的 Web 窗體。之后,會調用 Web 窗體的 RenderChildren 方法,它包含三行代碼:

    Page.OnFormRender(...) MyBase.RenderChildren(...) Page.OnFormPostRender(...)

    Page 類的 OnFormRender 方法的調用會添加以下標記:

    ?

    通過對 RegisterHiddenField 進行調用而添加的任意隱藏窗體字段。

    ?

    隱藏窗體字段中名為 __VIEWSTATE 的基于 64 位編碼的視圖狀態。

    ?

    通過對 RegisterClientScriptBlock 進行調用而添加的任意腳本塊。

    Web 窗體的 RenderChildren 方法中的第二行代碼調用基類的 RenderChildren 方法,它會在 Web 窗體中呈現內容。在呈現所有窗體的內容后,對 Page 類的 OnFormPostRender 方法進行調用,這將會添加以下客戶端內容:

    ?

    RegisterArrayDeclaration 方法添加的任意 Array 對象。

    ?

    通過對 RegisterStartupScript 進行調用而添加的任意腳本塊。

    最后,在 Web 窗體的 RenderChildren 方法完成后,則會呈現關閉窗體標記 ()。圖 2 以圖表形式說明了這個呈現過程。

    圖 2 假設您有些熟悉 ASP.NET 頁面的生命周期。如果您對學習更多有關頁面生命周期的知識感興趣,請考慮閱讀 Understanding ASP.NET View State,將重點放在標題為“The ASP.NET Page Life Cycle”的節上。


    2. ASP.NET 中呈現的頁面

    分析腳本塊的呈現順序

    乍看 Page 類的注冊方法,在網頁中呈現的已注冊元素的順序好像是對應于它們被添加到代碼中的順序。也就是說,設想 ASP.NET 網頁的代碼隱藏類中有以下兩行代碼:

    RegisterClientScriptBlock("showSaveMessage", _ "<script language=""JavaScript"">var name='" & _ someDataDrivenValue & "'; </script>") RegisterClientScriptBlock("showSaveMessage", _ "<script language=""JavaScript"">alert('Hello, ' + name + '!'); </script>")

    當發現頁面呈現以下客戶端腳本塊(假設 someDataDriveValue 的值為 Sam)時,您不要太奇怪:

    <script language="JavaScript">var name='Sam';</script> <script language="JavaScript">alert('Hello, ' + name + '!');</script>

    訪問該頁面的用戶將會看到一個警告框顯示“Hello, Sam!”。

    基于這個測試,您可能會認為這樣的事實始終成立:在 HTML 頁面中發出腳本塊的順序就是在服務器端代碼中為它們指定的順序。但是,這是一個不正確的假設,并且可以導致頁面中斷。例如,設想前面添加的腳本塊在 HTML 頁面中以相反的順序發出。那么,您將會得到:

    <script language="JavaScript">alert('Hello, ' + name + '!');</script> <script language="JavaScript">var name='Sam';</script>

    這將會顯示警告框“Hello, !”,因為變量 name 尚未分配值。顯然,有些時候發出腳本塊的順序非常重要的。

    Page 類的注冊方法 - RegisterClientScriptBlockRegisterStartupScriptRegisterArrayDeclarationRegisterHiddenFields - 全部將提供的腳本內容寫入到內部 HybridDictionary 中。HybridDictionary 是在 System.Collections.Specialized 命名空間中發現的數據結構,設計用于在有很多項目未知的字典中存儲項目。對于小型的項目集合,ListDictionary 是最有效的數據結構,但是對于較大的字典,Hashtable 會更有效。HybridDictionary 分離差異 - 它通過使用 ListDictionary 存儲項目來開始。當 ListDictionary 添加了它的第九個項目后,HybridDictionary 會從使用 ListDictionary 切換到使用 Hashtable

    盡管這種方法對于性能而言非常理想,但是如果您使用幾個腳本塊而且腳本塊的順序非常重要,那么它可能會帶來嚴重的破壞。這是因為,ListDictionary 維護元素被添加的順序,而 Hashtable 沒有進行維護。因此,如果您將八個或更少項目添加到任意一個特定的注冊方法中,項目將會以它們被添加的順序發出。但是,如果添加了第九個項目,腳本發出的順序看起來將是隨機的。

    ListDictionary 使用 linked list 存儲它的元素,而 Hashtable 將它的元素存儲在數組中,該數組的內容按照字符串鍵的哈希值進行排序。有關鏈接列表和哈希表的完整討論已經遠遠超出了本文所討論的范圍。有關詳細信息,包括對其性能的分析,請考慮閱讀 An Extensive Examination of Data Structures,尤其是 Part 2Part 4

    如果您計劃出現如下情況:可能會存在使用特殊注冊方法添加的多于八個客戶端元素,并且元素的出現順序比較重要,那么您可能希望研究一下 Peter Blum 的免費的 RegisterScripts 庫。對于所發出客戶端元素的順序,RegisterScripts 提供了更大的控制能力,并且還提供了無需手動添加 <script> 標記的選項,當利用 RegisterClientScriptBlockRegisterStartupScript 方法包括客戶端腳本時,您必須添加此標記。

    根據對用戶操作的響應執行客戶端代碼

    對于插入頁面加載時運行的客戶端代碼而言,Page 類的注冊方法非常理想,但是在很多情況下,我們希望根據對最終用戶操作的響應來運行代碼。例如,我們可能希望當用戶單擊按鈕時顯示確認對話框,或者當下拉列表的選定項目發生變化時調用特殊的客戶端 JavaScript 功能。

    HTML 元素具有您可以點擊的大量客戶端事件,并且當觸發事件時可以執行客戶端代碼。所要求的標記只是在 HTML 元素的標記中作為一個屬性。例如,要在單擊某個按鈕時顯示警告框,可以添加以下代碼:

    <input type="button" value="Click me to see an alert box!" onclick="alert('Here it is!');" />

    要在客戶端事件觸發時運行客戶端代碼,可以將適當的屬性添加到 HTML 元素中。對于 Web 控件,可以借助于編程方式使用 Attributes 集合添加客戶端屬性。例如,設想您具有一個 TextBox Web 控件,只要呈現的文本框獲得焦點,您就希望它突出顯示為黃色。要完成上述操作,您要將 TextBox Web 控件的呈現 HTML 添加如下所示的代碼:

    <input type="text" onfocus="this.style.backgroundColor='yellow';" onblur="this.style.backgroundColor='white';" />

    要完成這個標記,我們可以借助編程方式通過 Attributes 集合設置 TextBox Web 控件的 onfocusonblur 客戶端屬性,如下所示:

    TextBoxControl.Attributes("onfocus") = "this.style.backgroundColor='yellow';" TextBoxControl.Attributes("onblur") = "this.style.backgroundColor='white';"

    將客戶端代碼與客戶端事件結合在一起的這種技術通常用于提供豐富的、交互式的用戶體驗。稍后,我們將會在本文中說明如何使用這種技術來顯示基于用戶操作的確認對話框。

    實現常用客戶端功能

    在我們研究 ASP.NET 方法(涉及動態地將客戶端腳本添加到網頁)后,讓我們將注意力轉移到這個知識。本文的其余部分重點講述常用客戶端任務,例如顯示警告框、確認框、彈出窗口等等。具體說來,我們將創建包含一組方法的類,這組方法可用在 ASP.NET 項目中,從而快速、便捷地提供這樣的功能。

    我們將要分析的、貫穿本文剩余部分的 Visual Basic .NET 代碼可以在本文的代碼下載中獲得。

    顯示警告框

    一個常用的客戶端要求就是顯示警告框。警告框是一個客戶端模式對話框,通常用于為最終用戶提供某些重要的信息。警告框的示例如圖 1 所示。警告框是通過客戶端 JavaScript alert 函數來進行顯示的,該函數接受一個單個的參數,即要顯示的消息。顯示警告框相當簡單和直接;實際上,本文前面已經顯示了一個示例。

    為了使頁面開發人員盡可能簡單的顯示警告框,讓我們創建一個名為 ClientSidePage 的類,其中包含一個名為 DisplayAlert(message) 的方法。這個類將會繼承 Page 類。想要利用這些客戶端 helper 方法的頁面開發人員需要使他們的代碼隱藏類繼承這個 ClientSidePage 類,而不是繼承默認的 Page 類。以下代碼顯示了帶有其第一個方法 DisplayAlertClientSidePage 類。

    Public Class ClientSidePage Inherits System.Web.UI.Page Public Sub DisplayAlert(ByVal message As String) RegisterClientScriptBlock(Guid.NewGuid().ToString(), _ "<script language=""JavaScript"">" & GetAlertScript(message) & "</script>") End Sub Public Function GetAlertScript(ByVal message As String) As String Return "alert('" & message.Replace("'", "\'") & "');" End Function End Class

    請注意,這個類派生自 System.Web.UI.Page 類。DisplayAlert 方法只是使用 RegisterClientScriptBlock 方法,在警告框中顯示提供的 message。由于這個方法可能會由單個頁面多次調用,每個調用將使用其密鑰的 GUID(是“全局唯一標識符”的首字母縮寫)。傳遞到 alert 函數的字符串會使用撇號分隔,message 中的任意撇號都必須進行轉義(JavaScript 將撇號轉義為 \')。

    要將這段代碼用于 ASP.NET Web 應用程序中,您需要將新類添加到 ASP.NET 應用程序中。在 Visual Studio .NET 中,右鍵單擊解決方案資源管理器中的 ASP.NET Web 應用程序項目名,然后選擇添加新類。然后,剪切上述代碼并將其粘貼到該類中。接下來,在要利用該代碼的 ASP.NET 網頁中,您需要修改代碼隱藏類,以便它從 ClientSidePage 類而不是從 Page 中繼承。以下代碼顯示了派生自 ClientSidePage 并使用 DisplayAlert 方法的示例代碼隱藏類。

    Public Class WebForm1 Inherits ClientSidePage Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load DisplayAlert("Hello, World!") End Sub ... End Class

    請注意,ClientSidePage 類不僅具有可以生成完整客戶端 <script> 元素的 DisplayAlert 方法,還具有可以返回客戶端腳本無 <script> 標記的 GetAlertScript 方法。第二個方法可用于您希望基于某個客戶端事件顯示警告的情況中。例如,如果您希望在特定文本框接收到焦點的任意時間顯示警告,可以將以下代碼添加到服務器端代碼隱藏類中:

    TextBoxControlID.Attributes("onfocus") = GetAlertScript(message)
    將焦點設置為頁面加載時的窗體字段

    您是否注意到當訪問 Google 時,焦點自動設置在搜索文本框呢?這一點小的“功能”使得搜索 Google 更快 - 在訪問 Google 時您不必再花費時間移動鼠標,然后單擊文本框。更確切的說,您只需在頁面加載時鍵入即可。將焦點設置到窗體字段(可以是文本框、單選按鈕、復選框或下拉列表)只要求幾行客戶端 JavaScript 代碼。讓我們將方法添加到 ClientSidePage 類,該類將在頁面加載時自動向指定的 Web 控件中添加焦點。這種方法需要發出如下所示的客戶端腳本:

    <script language="JavaScript"> function CSP_focus(id) { var o = document.getElementById(id); if (o != null) o.focus(); } </script> ... Form fields ... <input type="..." id="id of element to focus" ... /> ... Form fields ... <script language="JavaScript"> CSP_focus(id of element to focus); </script>

    客戶端函數 CSP_focus 接受字符串參數,窗體字段的 ID 被設置為焦點,并且從 DOM 中檢索 HTML 元素。然后,調用檢索元素的 focus() 函數。在網頁的底部,在指定所有窗體字段后,我們需要調用 CSP_focus 方法,該方法在想要設置焦點的窗體字段的 ID 中傳遞。

    下面的方法 GiveFocus(Control) 使用 RegisterClientScriptBlockRegisterStartupScript 方法來生成所需要的客戶端腳本。

    Public Sub GiveFocus(ByVal c As Control) RegisterClientScriptBlock("CSP-focus-function", _ "<script language=""JavaScript"">" & vbCrLf & _ "function CSP_focus(id) {" & _ " var o = document.getElementById(id); " & _ "if (o != null) o.focus(); " & _ "}" & vbCrLf & _ "</script>") RegisterStartupScript("CSP-focus", _ "<script language=""JavaScript"">CSP_focus('" & _ c.ClientID & "');</script>") End Sub

    要從其代碼隱藏類繼承 ClientSidePage 的 ASP.NET 網頁中使用 GiveFocus 方法,可以簡單地在 Page_Load 事件處理程序中調用 GiveFocus,并傳遞應該在頁面加載時設置其焦點的 Web 控件。例如,要將焦點設置為 TextBox Web 控件 TextBoxControl,請使用以下 Page_Load 事件處理程序:

    Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load GiveFocus(TextBoxControl) End Sub
    打開彈出窗口

    盡管彈出窗口作為廣告發布者的工具在 Internet 上早已臭名昭著,但是很多 Web 應用程序還是因為使用彈出窗口而得到了好處。例如,您想要某個頁面在 DataGrid 中顯示數據庫項目的列表,同時帶有可以編輯每個特定項目的鏈接。不再使用 DataGrid 的內聯編輯功能,您可能希望在用戶選擇編輯 DataGrid 時打開彈出窗口,其中彈出窗口包含帶有可編輯 DataGrid 字段的文本框列表。(您希望這么做的一個原因在于可能存在大量的可編輯字段,但是您只想顯示 DataGrid 中最適當的字段,因此要消除使用 DataGrid 的內置編輯功能的可能性。)

    要顯示彈出窗口,請使用 JavaScript 函數 window.open(),它使用很多可選輸入參數,其中三個密切相關的參數是:

    ?

    加載彈出窗口的 URL。

    ?

    彈出窗口的字符串名稱。

    ?

    彈出窗口的特性,例如高度和寬度、窗口是否可以調整大小等等。

    window.open() 函數的完整討論已經超出了本文的范圍;要學習更多內容,請參閱技術文檔

    與其他顯示警告框的方法相似,ClientSidePage 類包含用于顯示彈出窗口的兩個方法 - 一個呈現顯示窗口的自包含 <script> 塊,另一個僅返回 JavaScript 腳本本身。除了打開彈出窗口的方法外,還有一組關閉當前窗口的方法。(可能會出現這樣的情況,您希望以編程方式基于某些客戶端或服務器端事件來關閉彈出窗口。)

    Public Sub DisplayPopup(ByVal url As String, ByVal options As String) RegisterStartupScript(Guid.NewGuid().ToString(), _ "<script language=""JavaScript"">" & _ GetPopupScript(url, options) & _ "</script>") End Sub Public Function GetPopupScript(ByVal url As String, _ ByVal options As String) As String Return "var w = window.open(""" & _ url & """, null, """ & options & """);" End Function Public Sub CloseWindow(Optional ByVal refreshParent As Boolean = False) RegisterClientScriptBlock("CSP-close-popup", _ "<script language=""JavaScript"">" & _ GetCloseWindowScript(refreshParent) & "</script>") End Sub Public Function GetCloseWindowScript(Optional _ ByVal refreshParent As Boolean = False) As String Dim script As String If refreshParent Then script &= "window.opener.location.reload();" End If Return "self.close();" End Function

    該代碼的執行示例可以在本文的代碼下載中找到。同時,您還將發現一個示例網頁,它具有一個在與 ASP.NET 網頁相同的目錄中列出文件的 DataGrid。這個 DataGrid 具有兩列:顯示超級鏈接的 TemplateColumn,當單擊時打開顯示所選文件內容的彈出窗口;以及該文件的名稱(如圖 3 所示)。


    3. 帶有彈出窗口的 DataGrid

    DataGrid 的標記利用 GetPopupScript 方法,如下所示:

    <asp:DataGrid id="dgFiles" runat="server" ...> <Columns> <asp:TemplateColumn HeaderText="View"> <ItemTemplate> <a href='javascript:<%# GetPopupScript("ViewFile.aspx?FileName=" & DataBinder.Eval(Container.DataItem, "Name"), "scrollbars=yes,resizable=yes,width=500,height=400") %>'> View File</a> </ItemTemplate> </asp:TemplateColumn> <asp:BoundColumn DataField="Name" HeaderText="Filename"></asp:BoundColumn> </Columns> </asp:DataGrid>

    ASP.NET 網頁 ViewFile.aspx 打開其名稱在 querystring 中指定的文件并顯示其內容(如圖 4 所示)。


    4. 在彈出窗口中顯示 Web.config 的內容

    彈出窗口最適用于只有 Intranet 應用程序的情況,因為很多 Internet 用戶利用某種彈出阻止軟件,例如 Google 工具欄。實際上,利用 Microsoft Windows XP Service Pack 2,Microsoft Internet Explorer 將會在默認情況下配置為阻止彈出窗口。但是,當用戶訪問受信任站點或本地 Intranet 區域中的站點時,彈出窗口將仍然會出現。有關在 Windows XP Service Pack 2 中阻止 Internet Explorer 彈出窗口功能的詳細信息,請務必閱讀 Changes to Functionality in Microsoft Windows XP Service Pack 2

    在回發前確認

    在本文的前面部分,我們研究了如何顯示客戶端警告框,這是帶有“OK”按鈕的模式對話框。JavaScript 提供被稱為確認對話框的更具有交互風格的警告框。使用 confirm(message) 函數顯示確認對話框并通過 message 輸入參數與“OK”和“Cancel”按鈕指定顯示帶有文本的對話框的效果。如果用戶單擊“OK”,confirm(message) 函數會返回 true;如果他們單擊“Cancel”,則返回 false。

    通常情況下,確認對話框用于確保用戶在提交窗體之前希望繼續。當單擊 HTML 元素(例如提交按鈕)提交窗體時,如果 HTML 元素觸發返回 false 的客戶端事件處理程序,窗體提交就被取消。通常,確認對話框用于網頁中,如下所示:

    <form ...> <input type="submit" value="Click Me to Submit the Form" onclick="return confirm('Are you sure you want to submit this form?');" /> </form>

    當用戶單擊“Click Me to Submit the Form”按鈕時,他們將會看到確認對話框,詢問他們是否確實希望提交該窗體(如圖 5 所示)。如果用戶單擊“OK”,confirm() 將返回 true,該窗體將被提交。但是,如果他們單擊“Cancel”按鈕,confirm() 將返回 false,該窗體提交將被取消。


    5. 確認 JavaScript 的結果

    設想您具有一個 DataGrid帶有標簽為“Delete”的一列按鈕。在單擊該按鈕時,該窗體將會回發,并且選定的記錄將被刪除。在此例中,您可能希望復查用戶是否確實希望刪除該記錄。此時,要使用客戶端確認對話框將會非常理想。您可以用對話框提示用戶,聲明如下所示的內容:“This will permanently delete the record.Are you sure you want to continue?”如果用戶單擊“OK”,該窗體將會回發,并且記錄將被刪除;如果他們單擊“Cancel”,該窗體將不會回發,而且記錄也不會被刪除。

    要添加在單擊按鈕后顯示確認對話框所必需的客戶端 JavaScript,請簡單地使用 Attributes 集合來添加客戶端 onclick 事件處理程序。具體說來,要將 onclick 事件處理程序代碼設置為:return confirm(message);。為了提供 DataGridButtonColumn 的這種功能,您需要在 DataGridItemCreatedItemDataBound 事件處理程序中以編程方式引用 ButtonLinkButton 控件,并且在那里設置 onclick 屬性。有關詳細信息,請參閱 http://aspnet.4guysfromrolla.com/articles/090402-1.aspx

    確認 AutoPostBack DropDownLists

    盡管通常在單擊按鈕時使用確認對話框,但是還可以在更改下拉列表時使用它們。例如,您可能具有一個當特定的 DropDownList Web 控件發生更改時會自動回發的網頁。(DropDownList Web 控件具有一個 AutoPostBack 屬性,如果設置為 True,只要 DropDownList 的選定項目發生更改就會導致窗體回發。)

    直觀地講,您可能認為對 DropDownList 添加確認對話框與對 Button Web 控件添加這種對話框相同。也就是說,簡單地將 DropDownList 的客戶端 onchange 屬性更改為如下內容:return confirm(...);。使用:

    DropDownListID.Attributes("onchange") = "return confirm(...);"

    遺憾的是,這并不會按期望工作,因為 AutoPostBackDropDownListonchange 屬性將設置為會導致回發的 JavaScript,即對客戶端 __doPostBack 函數的調用。當您自己借助編程方式設置 onchange 屬性時,最后的結果是呈現的客戶端 onchange 事件處理程序同時具有您的代碼和對 __doPostBack 的調用:

    <select onchange="return confirm(...);__doPostBack(...);"> ... </select>

    記住,我們確實希望發生的情況是,如果確認返回 true,就調用 __doPostBack 函數,因為之后頁面將會被回發。通過利用 Attributes 集合將 onchange 事件設置為:if (confirm(...)),我們可以完成這一操作,而該代碼會生成以下標記,該標記正是我們所希望的:

    <select onchange="if (confirm(...)) __doPostBack(...);"> ... </select>

    乍看起來,這似乎會具有所期望的效果。如果用戶從下拉列表中選擇不同的項目,將會出現一個確認框。如果用戶單擊“OK”,該窗體將回發;如果用戶單擊“Cancel”,該窗體回發會暫停。盡管問題在于下拉列表維持用戶選定的項目以啟動下拉列表的 onchange 事件。例如,設想下拉列表加載正在進行選擇的項目 x,然后用戶選擇項目 y。這將會觸發下拉列表客戶端 onchange 事件,它將會顯示確認對話框。現在,設想用戶點擊“Cancel”- 下拉列表將仍然選擇項目 y。我們希望的是將選擇轉回到項目 x。

    要實現此目的,我們需要做兩件事情:

    1.

    編寫一個“記住”選定下拉列表項目的 JavaScript 函數。

    2.

    在下拉列表的客戶端 onchange 事件中,如果用戶單擊“Cancel”,您需要將下拉列表轉換回“已記住的”值。

    步驟 1 必須為下拉列表和函數(當頁面加載時運行,并且記錄下拉列表的值)創建全局腳本變量。步驟 2 要求為下拉列表的客戶端 onchange 屬性更改為如下所示內容:

    if (!confirm(...)) resetDDLIndex(); else __doPostBack();

    其中 resetDDLIndex 是 JavaScript 函數,它將下拉列表選定的值返回到“已記住的”值。用于此目的的客戶端腳本應該如下所示:

    <select id="ddlID" onchange="if (!confirm(...)) resetDDLIndex(); else __doPostBack(...);"> ... </select> <script language="JavaScript"> var savedDDLID = document.getElementById("ddlID").value; function resetDDLIndex() { document.getElementById("ddlID").value = savedDDLID; } </script>

    通過在 ClientSidePage 類中創建 helper 方法,這個必要的腳本可以輕松地生成。

    Public Sub ConfirmOnChange(ByVal ddl As DropDownList, ByVal message As String) 'Register the script block If Not IsStartupScriptRegistered("CSP-ddl-onchange") Then RegisterStartupScript("CSP-ddl-onchange", _ "<script language=""JavaScript"">" & _ "var CSP_savedDDLID = " & _ document.getElementById('" & _ ddl.ClientID & "').value;" & vbCrLf & _ "function resetDDLIndex() {" & vbCrLf & _ " document.getElementById('" & " & _ " ddl.ClientID & "').value = CSP_savedDDLID;" & vbCrLf & _ "}" & vbCrLf & _ "</script>") End If ddl.Attributes("onchange") = _ "if (!confirm('" & message.Replace("'", "\'") & _ "')) resetDDLIndex(); else " End Sub

    要使用這段代碼,簡單地調用網頁上每個 AutoPostBackDropDownList 的該方法,當網頁上的選定項目發生更改時要在該網頁上顯示對話框。

    未保存而退出時進行確認

    在我所創建的大多數每個數據驅動的 Web 應用程序中,始終會有用戶可以編輯數據庫特定信息的特定頁面。非常簡單的一個示例是帶有一系列 TextBoxDropDownList Web 控件的頁面,而數據庫數據填充在這些控件中。用戶可以進行任何適當的修改,然后單擊“Save”按鈕將他們所做的更改保存到數據庫。

    當我創建這些頁面時,通常會以兩個 Button Web 控件來結束頁面:“Save”按鈕和“Cancel”按鈕。“Save”按鈕將任意更改保存回數據庫,而“Cancel”按鈕不保存任何更改退出頁面。盡管兩個按鈕看起來可能是一個完美的設計,但有時用戶會在他們想要單擊“Save”按鈕時意外地單擊“Cancel”按鈕,這樣就會丟失了他們對數據所做的所有更改。為防止這種情況發生,可以在“Cancel”按鈕上使用確認框,它只有在網頁上的任意文本框或下拉列表發生更改時才會出現。也就是說,如果用戶對數據進行了任意更改,然后單擊“Cancel”,確認框將會提示他們是否確實要在不保存的情況下退出。(如果用戶只是單擊“Cancel”,而沒有更改任何數據,將不會顯示這樣的確認框。)

    這種用戶體驗可以通過少量客戶端 JavaScript 來實現。基本上可以說,它需要一個 JavaScript 全局變量 isDirty,在初始時為 false,但只要觸發窗體字段的 onchange 事件,它就會設置為 true。如果 isDirty 為 true,則還有一個顯示確認對話框的 JavaScript 函數。“Cancel”按鈕的 onclick 客戶端事件處理程序限定為從該 JavaScript 函數返回結果。以下 HTML 說明了這個概念:

    <script language="JavaScript"> var isDirty= false; function checkForChange(msg) { if (isDirty) return confirm(msg); else return true; } </script> Name: <input type="text" onchange="isDirty = true;" /> <input type="submit" name="btnSave" value="Save" id="btnSave" /> <input type="submit" name="btnCancel" value="Cancel" id="btnCancel" onclick="return checkForChange('You have made changes to the data since last saving. If you continue, you will lose these changes.');" />

    可以通過將該腳本生成移動到 ClientSidePage 類,簡單地生成這個腳本。具體說來,我們可以創建下列三個方法:

    Protected Sub RegisterOnchangeScript() If Not IsClientScriptBlockRegistered("CSP-onchange-function") Then RegisterClientScriptBlock("CSP-onchange-function", _ "<script language=""JavaScript"">" & _ "var isDirty= false;" & vbCrLf & _ "function CSP_checkForChange(msg) {" & vbCrLf & _ " if (isDirty) return confirm(msg); " & _ "else return true;" & vbCrLf & _ "}" & vbCrLf & _ "</script>") End If End Sub Public Sub MonitorChanges(ByVal c As WebControl) RegisterOnchangeScript() If TypeOf c Is CheckBox Or TypeOf c Is CheckBoxList _ Or TypeOf c Is RadioButtonList Then c.Attributes("onclick") = "isDirty = true;" Else c.Attributes("onchange") = "isDirty = true;" End If End Sub Public Sub ConfirmOnExit(ByVal c As WebControl, ByVal message As String) RegisterOnchangeScript() c.Attributes("onclick") = _ "return CSP_checkForChange('" & message.Replace("'", "\'") & "');" End Sub

    要創建表現這個行為的網頁,我們只需要將其服務器端代碼隱藏類派生自 ClientSidePage,并且在 Page_Load 事件處理程序中,為需要客戶端 onchange 事件的每個 Web 控件對 MonitorChanges 進行調用,并且為在單擊時應該顯示警告用戶是否進行更改并退出頁面的每個 ButtonLinkButtonImageButton,對 ConfirmOnExit 進行調用。

    MonitorChanges 方法使用 onclick 客戶端事件,而不是用于 CheckBoxCheckBoxListRadioButtonList Web 控件的 onchange。這是因為這些控件將 <span> 標記或 <table> 限制在復選框或很多復選框或單選按鈕附近。在我利用 Internet Explorer 進行測試時,我發現在應用到 <span> 或 <table> 時,選中復選框或單擊單選按鈕并沒有選擇 onchange 事件,但是卻觸發了 onclick 事件。

    圖 6 顯示了帶有兩個 TextBox Web 控件、一個 DropDownList Web 控件和一個 CheckBox Web 控件的 ASP.NET 網頁示例。如下面的 Page_Load 事件處理程序所示,所有這些 Web 控件都會被監視所做的更改。配置“Cancel”按鈕 btnCancel,這樣如果在進行更改后單擊它,將顯示一個確認對話框。


    6. 帶有確認的對話框

    Public Class ConfirmOnExit Inherits ClientSidePage Private Sub Page_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles MyBase.Load 'Specify what controls to check for changes MonitorChanges(name) MonitorChanges(age) MonitorChanges(favColor) MonitorChanges(chkSilly) ConfirmOnExit(btnCancel, _ "You have made changes to the data since last saving." & _ " If you continue, you will lose these changes.") End Sub ... End Class

    客戶端 onchange 事件不能用于 Netscape 的舊版本中。同樣,Internet Explorer 5.0 的 onchange 事件也具有一些已報告的問題(在 Internet Explorer 5.01 SP 1 中已經修復)。

    而且,這種方法將不會像利用 DropDownList Web 控件那樣將 AutoPostBack 設置為 True,而是回發將重置 isDirty 的值。這個問題有很多解決方案,例如使用隱藏窗體字段,指示出回發窗體數據是否以 dirty 開始。我將實現這個操作的過程作為練習留給讀者。

    創建客戶端 MessageBox 控件

    由于確認對話框是一種防止意外點擊的非常好的方法,可以潛在地降低到 Web 服務器的回發數量,有幾種特定方案您可能希望顯示確認對話框,并且能夠在服務器端確定用戶是否單擊了“OK”或“Cancel”。(記住,對于確認對話框,如果用戶單擊“Cancel”,該窗體則不會回發。)而且,JavaScript 中的警告和確認框在外觀上非常受限。幸運的是,客戶端 VBScript 通過其 MsgBox 函數提供了更豐富的消息框體驗。

    在過去的項目中,我需要客戶端模式消息框,無論單擊什么按鈕,它都可以引起回發。作為響應,我構建了自定義編譯的 ASP.NET 服務器控件來滿足這些要求。此外,客戶端消息框還使用 VBScript 的 MsgBox 函數來提供更豐富的消息框體驗。

    在 Microsoft Internet Explorer 瀏覽器中,VBScript 只作為客戶端腳本編輯語言。要考慮到這一點,如果訪問瀏覽器是 Internet Explorer,那么我的服務器控件只能使用 VBScript。如果是非 Internet Explorer 瀏覽器,則服務器端控件使用 JavaScript。

    對這種自定義服務器控件深入的討論可以完全保證整個文章的正確性,因此無需將重點放在控件的內部工作原理上,讓我們分析如何在 ASP.NET 網頁中使用 MessageBox 控件。(控件的完整資源以及使用該控件的示例 ASP.NET 網頁都可以從本文的下載中獲得。)

    要在 ASP.NET 網頁中使用 MessageBox 控件,首先要將 MessageBox 控件添加到 Visual Studio .NET 工具箱。通過右鍵單擊工具箱、從工具箱中選擇“Add/Remove Items”、然后瀏覽到 MessageBox 程序集可以實現上述任務。要將客戶端消息框添加到網頁,只要將其從工具箱拖動到該設計器即可。圖 7 顯示了 Visual Studio .NET 設計器中的 MessageBox 控件。


    7. 顯示模式消息框

    MessageBox 類具有很多可以進行配置的屬性,以調整消息框的外觀:

    ?

    Buttons. 指定要顯示的按鈕。ButtonOptions 枚舉中定義的選項可以為:OkOnly、OkCancel、AbortRetryIgnore、YesNoCancel、YesNo 或 RetryCancel。

    ?

    DisplayWhenButtonClicked. 點擊后將顯示客戶端消息框的按鈕 Web 控件的 ID。如果希望由于點擊某個特定按鈕而顯示消息框,請使用這個屬性。

    ?

    Icon. 顯示在消息框中的圖標;選項定義于 IconOptions 枚舉中。有效的值為:Critical、Question、Exclamation 和 Information。

    ?

    Prompt. 顯示在消息框中的文本。

    ?

    Title. 消息框的標題。

    一旦將 MessageBox 控件添加到 ASP.NET 網頁,下一個挑戰就是使其根據特定客戶端操作進行顯示。DisplayWhenButtonClicked 屬性允許您指定頁面上按鈕 Web 控件的 ID點擊后將會顯示消息框。另外,您還可以通過調用客戶端函數 mb_show(id) 來顯示消息框,其中 IDMessageBox 控件的 ID

    不管您選擇在消息框中顯示什么按鈕配置,當單擊任意按鈕時,隨后就會發生回發并且觸發 MessageBox 控件的 Click 事件。通過在設計器中簡單地雙擊 MessageBox,可以為此事件創建一個事件處理程序。事件處理程序的第二個輸入參數是類型 MessageBoxClickedEventArgs,它包含一個返回用戶單擊消息框按鈕的信息的 ButtonClicked 屬性。

    MessageBox 控件在如下情況下非常有用,當您希望快速為用戶提供模式對話框,而不管用戶的選擇以及回發中的結果。要查看操作中的 MessageBox 控件,請簽出源代碼下載中的 MsgBoxDemo.aspx 頁面。

    小結

    本文一開始就研究了網頁中客戶端腳本的常見使用,然后轉向分析將客戶端腳本插入到 ASP.NET 網頁中的方法和技術。正如我們看到的那樣,Page 類包含很多旨在借助編程方式從服務器端代碼隱藏類插入客戶端腳本塊的方法。這些方法也常用于自定義編譯的服務器控件,請參閱我以前文章中的討論: Injecting Client-Side Script from an ASP.NET Server Control.

    除了添加腳本塊外,客戶端功能通常必須與由某些 HTML 元素引發的客戶端事件結合在一起。要借助編程方式通過服務器端代碼隱藏類指定 Web 控件的客戶端事件處理程序,請使用 Attributes 集合,它可用作所有 Web 控件的屬性。

    本文的后半部分應用了前半部分中涉及的內容,顯示了如何在 ASP.NET 網頁中實現常用客戶端功能。我們看到了如何擴展 Page 類,這樣我們可以利用代碼隱藏類輕松地顯示警告框、將頁面加載上的焦點設置到特定 Web 控件、如何顯示彈出窗口以及如何顯示確認對話框。我們還研究了創建自定義服務器控件,它使用 VBScript 來提供更豐富的客戶端消息框用戶體驗,而且無需考慮單擊按鈕就可以導致回發。

    祝大家編程愉快!

    特別感謝...

    在我將文章提交給 MSDN 編輯之前,有很多志愿者幫助我對本文進行校對并為本文的內容、語法和目的提供了反饋。本文校對過程中的主要貢獻者包括 Maxim KarpovCarlos SantosMilan Negovan 和 Carl Lambrecht。如果您有興趣加入到不斷增長的校對人員中,請給我發郵件 mitchell@4guysfromrolla.com

    關于作者

    Scott Mitchell 著有五本書,他是 4GuysFromRolla.com 網站的創始人,過去五年來一直從事 Microsoft Web 技術方面的研究。Scott 是一位獨立的顧問、培訓師和作家。您可以通過 mitchell@4guysfromrolla.com 與作者進行聯絡,或者通過作者的 blog 進行聯絡,其網址是:http://ScottOnWriting.NET

    posted on 2005-12-08 21:16 天外飛仙 閱讀(466) 評論(0)  編輯  收藏 所屬分類: .net
    主站蜘蛛池模板: 日本红怡院亚洲红怡院最新| 国产亚洲精品高清在线| 亚洲av无码乱码国产精品fc2| 黄色毛片免费网站| 亚洲日韩在线中文字幕第一页| 羞羞的视频在线免费观看| 免费观看午夜在线欧差毛片 | 91视频国产免费| 麻豆狠色伊人亚洲综合网站| 亚洲精品无码久久不卡| 免费视频成人国产精品网站| 亚洲中文字幕成人在线| 精品国产污污免费网站入口| 亚洲AV午夜成人影院老师机影院| 香蕉免费一区二区三区| 亚洲成综合人影院在院播放| 毛片免费观看的视频| 精品久久久久久亚洲中文字幕| 亚洲国产精品无码久久青草| 大妹子影视剧在线观看全集免费| 日本亚洲视频在线| 三年片在线观看免费大全| 亚洲Av永久无码精品一区二区| 亚洲AV无码成人精品区大在线| 中文字幕一区二区三区免费视频| 亚洲国产精品第一区二区| 国拍在线精品视频免费观看| 在线A亚洲老鸭窝天堂| 午夜理伦剧场免费| 亚洲熟伦熟女专区hd高清| 亚洲人成影院在线观看| 日韩免费无码视频一区二区三区 | 一级毛片免费在线观看网站| 久久久久久亚洲精品| 四虎永久在线观看免费网站网址| 亚洲日本VA午夜在线电影| 在线观看www日本免费网站| 亚洲av中文无码字幕色不卡 | 国产精品亚洲精品观看不卡| 免费成人av电影| 91精品国产免费久久国语麻豆|