在客户端脚本中为 UpdateProgress 控件编程
更新:2007 年 11 月
在本教程中,将通过编写 ECMAScript (JavaScript) 代码来扩展具有客户端行为的 UpdateProgress 控件。您的代码将使用属于 Microsoft AJAX Library 的一部分的 PageRequestManager 类。在 UpdateProgress 控件中,您将添加一个使用户能够取消异步回发的按钮。作为此任务的一部分,您将使用客户端脚本来显示或隐藏进度消息。
本主题假定您了解 UpdateProgress 控件。如果不了解,请查看主题 UpdateProgress 控件介绍。
先决条件
若要在您自己的开发环境中实现这些过程,您需要:
Microsoft Visual Studio 2005 或 Visual Web Developer 速成版。
一个支持 AJAX 的 ASP.NET 网站。
在客户端脚本中取消异步回发
创建新的 ASP.NET 网页并切换到“设计”视图。
在工具箱的**“AJAX Extensions”**选项卡中双击 ScriptManager 控件、UpdatePanel 控件和 UpdateProgress 控件以将每个控件的一个实例添加到页中。
从工具箱的**“标准”**选项卡,将 Label 控件添加到 UpdatePanel 控件,并将标签的 Text 属性设置为“呈现的面板”。
将 Button 控件添加到 UpdatePanel 控件,并将其 Text 属性设置为“刷新”。
在 UpdateProgress 控件中,添加文本“正在处理...”。
从工具箱的**“HTML”**选项卡,将 HtmlButton 控件添加到 UpdateProgress 控件,并将其 Value 属性设置为“取消”。
双击“刷新”按钮以便为其 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 Sub
protected 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 毫秒。
再次单击“刷新”,然后立即单击“取消”以停止部分页更新。
请注意,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 runat="server"> 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 runat="server"> <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" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"/> <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" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="refresh" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <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 runat="server"> 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 runat="server"> <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" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"/> <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" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button2" runat="server" OnClick="Button1_Click" Text="refresh" /> </ContentTemplate> </asp:UpdatePanel> </div> <asp:UpdateProgress ID="UpdateProgress1" runat="server"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </form> </body> </html>
使用客户端脚本显示更新进度
在下列方案中,将不会自动显示 UpdateProgress 控件:
UpdateProgress 控件与某个特定的更新面板相关联,但异步回发是从一个未位于该更新面板内的控件引发的。
UpdateProgress 控件不与任何 UpdatePanel 控件相关联,并且异步回发不是从一个既不位于 UpdatePanel 内部也不是一个触发器的控件引发。例如,使用代码执行更新。
下面的过程演示如何在异步回发并非来自关联的 UpdatePanel 控件内部时显示 UpdateProgress 控件。此过程假定您已完成本教程的第一部分。
以编程方式显示 UpdateProgress 控件
在前面创建的页中,切换到“设计”视图。
选择 UpdateProgress 控件,并在“属性”窗口中将 AssociatedUpdatePanelID 属性设置为 UpdatePanel1。
将 Button 控件添加到 UpdatePanel 和 UpdateProgress 控件外部的任一位置。
将按钮的 Text 属性设置为“触发器”,并将其 ID 设置为“Panel1Trigger”。
选择 UpdatePanel 控件,然后在“属性”窗口中单击 Triggers 属性框中的省略号 (…)。
将显示**“UpdatePanelTrigger 集合编辑器”**对话框。
创建一个 AsyncPostBackTrigger 对象并将其 ControlID 属性设置为“Panel1Trigger”。
单击**“确定”**以关闭集合编辑器。
双击“触发器”按钮,以便为其 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 Sub
protected 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 控件中的消息显示时间。
单击“触发器”按钮。
请注意,将显示进度消息。
<%@ Page Language="VB" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> 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" runat="server"> <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" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <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" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" runat="server" Text="refresh" OnClick="Button1_Click" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Panel1Trigger" /> </Triggers> </asp:UpdatePanel> <asp:Button ID="Panel1Trigger" runat="server" Text="Trigger" OnClick="Panel1Trigger_Click" /> <asp:UpdateProgress ID="UpdateProgress1" runat="server" 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 runat="server"> 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" runat="server"> <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" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server" /> <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" runat="server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Panel rendered."></asp:Label><br /> <asp:Button ID="Button1" runat="server" Text="refresh" OnClick="Button1_Click" /> </ContentTemplate> <Triggers> <asp:AsyncPostBackTrigger ControlID="Panel1Trigger" /> </Triggers> </asp:UpdatePanel> <asp:Button ID="Panel1Trigger" runat="server" Text="Trigger" OnClick="Panel1Trigger_Click" /> <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1"> <ProgressTemplate> Processing... <input id="Button2" type="button" value="cancel" onclick="CancelAsyncPostBack()" /> </ProgressTemplate> </asp:UpdateProgress> </div> </form> </body> </html>
回顾
本教程演示了可通过编写 JavaScript 代码来扩展 UpdateProgress 控件的行为的方法。可以使用 PageRequestManager 类的事件和方法来取消异步回发,并以编程方式显示和隐藏 UpdateProgress 控件。