更新:2007 年 11 月
在此教學課程中,您將透過撰寫 ECMAScript (JavaScript) 程式碼,以用戶端行為擴充 UpdateProgress 控制項。您的程式碼將使用 PageRequestManager 類別,此類別是 Microsoft AJAX Library 的一部分。在 UpdateProgress 控制項中,您將加入可讓使用者可以取消非同步回傳的按鈕。在執行此工作時,您將使用用戶端指令碼來顯示或隱藏進度訊息。
這個主題假設您已熟悉 UpdateProgress 控制項。如果不熟悉,請檢閱UpdateProgress 控制項簡介主題。
必要條件
若要在自己的開發環境中實作這些程序,您需要:
Microsoft Visual Studio 2005 或 Visual Web Developer Express 版。
具備 AJAX 能力的 ASP.NET 網站。
在用戶端指令碼中取消非同步回傳
建立新的 ASP.NET Web 網頁並切換至 [設計] 檢視。
在工具箱的 [AJAX 擴充功能] 索引標籤中,按兩下 ScriptManager 控制項、UpdatePanel 控制項與 UpdateProgress 控制項,將每個控制項的執行個體加入網頁中。
.png)
從工具箱的 [標準] 索引標籤,加入 Label 控制項至 UpdatePanel 控制項,並將該標籤的 Text 屬性設定為 Panel Rendered。
加入 Button 控制項至 UpdatePanel 控制項,並將其 Text 屬性設定為 Refresh。
在 UpdateProgress 控制項中,加入文字 Processing…。
從工具箱的 [HTML] 索引標籤,加入 HtmlButton 控制項至 UpdateProgress 控制項,並將其 Value 屬性設定為 Cancel。
.png)
按兩下 [Refresh] 按鈕,為其 Click 事件加入事件處理常式。
將下列程式碼加入至 Click 處理常式,可用手動方式造成三秒鐘的延遲,然後將標籤設定為目前的伺服器時間。
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() End Subprotected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString(); }
注意事項:在此教學課程中,Click 事件的處理常式會故意造成延遲。實際上,延遲並非由您造成。此延遲是因伺服器流量或需要長時間執行的伺服端程式碼 (例如,需長時間執行的資料庫查詢) 所造成。
在 <asp:ScriptManager> 項目下,加入下列指令碼:
<script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script><script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script>指令碼會取得 PageRequestManager 類別的目前執行個體。接著,它會建立呼叫 abortPostBack 方法的函式,以停止非同步回傳。
將 HtmlButton 控制項的 onclick 屬性設定為 CancelAsyncPostBack,亦即您在上一個步驟中所建立之處理常式的名稱。
<input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /><input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" />將下列樣式區塊加入至 <head> 項目:
<style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style><style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style>樣式設定會將 UpdateProgress 控制項設定為顯示在瀏覽器視窗的左下角。
儲存變更,然後按 CTRL+F5 在瀏覽器中檢視頁面。
按一下 [重新整理]。
在短暫的延遲之後,會顯示進度訊息。允許網頁局部完成更新,以便變更 UpdatePanel 控制項中的訊息來顯示時間。
注意事項:您可以設定 DisplayAfter 屬性以設定延遲時間。預設值為 500 毫秒。
再按一下 [Refresh],然後立即按一下 [ Cancel],停止網頁局部更新。
請注意,UpdatePanel 中的時間不會重新整理。
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head > <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" /> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:Label ID="Label1" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" OnClick="Button1_Click" Text="refresh" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:UpdateProgress ID="UpdateProgress1" > <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </form> </body> </html><%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString(); } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head > <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" /> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:Label ID="Label1" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button2" OnClick="Button1_Click" Text="refresh" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:UpdateProgress ID="UpdateProgress1" > <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </form> </body> </html>
使用用戶端指令碼顯示更新進度
在下列案例中,UpdateProgress 控制項將不會自動顯示:
UpdateProgress 控制項與特定更新面板關聯,但非同步回傳產生於該更新面板之外的控制項。
UpdateProgress 控制項未與任何 UpdatePanel 控制項關聯,而且非同步回傳不會產生於 UpdatePanel 之外且不是觸發程序 (Trigger) 的控制項。例如,更新是以程式碼執行。
下列程序說明當非同步回傳不是從關聯之 UpdatePanel 控制項內產生時,如何顯示 UpdateProgress 控制項。這個程序會假設您已完成此教學課程中的第一個部分。
以程式設計方式顯示 UpdateProgress 控制項
在您稍早建立的網頁中,切換到 [設計] 檢視。
選取 UpdateProgress 控制項,然後在 [屬性] 視窗中,將 AssociatedUpdatePanelID 屬性設定為 UpdatePanel1。
.png)
在 UpdatePanel 與 UpdateProgress 控制項以外的地方加入 Button 控制項。
將按鈕的 Text 屬性設定為 Trigger,並將其識別碼設定為 Panel1Trigger。
.png)
選取 UpdatePanel 控制項,並在 [屬性] 視窗中按一下 Triggers 屬性方塊中的省略符號 (…)。
[UpdatePanelTrigger 集合編輯器] 對話方塊隨即顯示。
建立 AsyncPostBackTrigger 物件,並將其 ControlID 屬性設定為 Panel1Trigger。
.png)
按一下 [確定],關閉集合編輯器。
按兩下 [Trigger] 按鈕,為其 Click 事件加入事件處理常式。
將下列程式碼加入 Click 處理常式,這樣可用手動方式建立三秒鐘的延遲。接著它會顯示伺服器時間與訊息,說明回傳是由觸發程序產生。
Protected Sub Panel1Trigger_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() & " - trigger" End Subprotected void Panel1Trigger_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString() + " - trigger"; }在 [原始碼] 檢視中,將下列用戶端指令碼加入至網頁中的現有 <script> 區塊下方。
prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } }prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } }指令碼會執行下列動作:
它會定義 PageRequestManager 類別之 initializeRequest 事件的處理常式。處理常式程式碼會取消任何執行中的非同步回傳。否則,若回傳來自 Panel1Trigger<div> 項目,則程式碼會顯示 UpdateProgress 範本。
它會定義 PageRequestManager 類別之 endRequest 事件的處理常式。若回傳來自 Panel1Trigger<div> 項目,則處理常式程式碼會隱藏進度控制項。
下列範例顯示完整的指令碼區塊。
<script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script><script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script>儲存變更,然後按 CTRL+F5 在瀏覽器中檢視頁面。
按一下 [重新整理] 按鈕。
在短暫的延遲之後,會顯示進度訊息。允許網頁局部完成更新,以便 UpdatePanel 控制項中的訊息顯示時間。
按一下 [Trigger] 按鈕。
請注意,現在會顯示進度訊息。
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() End Sub Protected Sub Panel1Trigger_Click(ByVal sender As Object, ByVal e As System.EventArgs) System.Threading.Thread.Sleep(3000) Label1.Text = DateTime.Now.ToString() & " - trigger" End Sub </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" > <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" /> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:Label ID="Label1" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" Text="refresh" OnClick="Button1_Click" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Panel1Trigger" /> </Triggers> </asp:UpdatePanel> <asp:Button ID="Panel1Trigger" Text="Trigger" OnClick="Panel1Trigger_Click" /> <asp:UpdateProgress ID="UpdateProgress1" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </div> </form> </body> </html><%@ Page Language="C#" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script > protected void Button1_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString(); } protected void Panel1Trigger_Click(object sender, EventArgs e) { System.Threading.Thread.Sleep(3000); Label1.Text = DateTime.Now.ToString() + " - trigger"; } </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head id="Head1" > <title>UpdateProgress Tutorial</title> <style type="text/css"> #UpdatePanel1 { width:200px; height:100px; border: 1px solid gray; } #UpdateProgress1 { width:200px; background-color: #FFC080; bottom: 0%; left: 0px; position: absolute; } </style> </head> <body> <form id="form1" > <div> <asp:ScriptManager ID="ScriptManager1" /> <script language="javascript" type="text/javascript"> <!-- var prm = Sys.WebForms.PageRequestManager.getInstance(); function CancelAsyncPostBack() { if (prm.get_isInAsyncPostBack()) { prm.abortPostBack(); } } prm.add_initializeRequest(InitializeRequest); prm.add_endRequest(EndRequest); var postBackElement; function InitializeRequest(sender, args) { if (prm.get_isInAsyncPostBack()) { args.set_cancel(true); } postBackElement = args.get_postBackElement(); if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'block'; } } function EndRequest(sender, args) { if (postBackElement.id == 'Panel1Trigger') { $get('UpdateProgress1').style.display = 'none'; } } // --> </script> <asp:UpdatePanel ID="UpdatePanel1" > <ContentTemplate> <asp:Label ID="Label1" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" Text="refresh" OnClick="Button1_Click" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Panel1Trigger" /> </Triggers> </asp:UpdatePanel> <asp:Button ID="Panel1Trigger" Text="Trigger" OnClick="Panel1Trigger_Click" /> <asp:UpdateProgress ID="UpdateProgress1" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </div> </form> </body> </html>
檢閱
此教學課程說明透過撰寫 JavaScript 指令碼擴充 UpdateProgress 控制項行為的方式。您可以使用 PageRequestManager 類別的事件與方法取消非同步回傳,並以程式設計方式顯示與隱藏 UpdateProgress 控制項。