在客户端脚本中为 UpdateProgress 控件编程

更新:2007 年 11 月

在本教程中,将通过编写 ECMAScript (JavaScript) 代码来扩展具有客户端行为的 UpdateProgress 控件。您的代码将使用属于 Microsoft AJAX Library 的一部分的 PageRequestManager 类。在 UpdateProgress 控件中,您将添加一个使用户能够取消异步回发的按钮。作为此任务的一部分,您将使用客户端脚本来显示或隐藏进度消息。

本主题假定您了解 UpdateProgress 控件。如果不了解,请查看主题 UpdateProgress 控件介绍

先决条件

若要在您自己的开发环境中实现这些过程,您需要:

  • Microsoft Visual Studio 2005 或 Visual Web Developer 速成版。

  • 一个支持 AJAX 的 ASP.NET 网站。

在客户端脚本中取消异步回发

  1. 创建新的 ASP.NET 网页并切换到“设计”视图。

  2. 在工具箱的**“AJAX Extensions”**选项卡中双击 ScriptManager 控件、UpdatePanel 控件和 UpdateProgress 控件以将每个控件的一个实例添加到页中。

    UpdateProgress 教程

  3. 从工具箱的**“标准”**选项卡,将 Label 控件添加到 UpdatePanel 控件,并将标签的 Text 属性设置为“呈现的面板”。

  4. Button 控件添加到 UpdatePanel 控件,并将其 Text 属性设置为“刷新”。

  5. UpdateProgress 控件中,添加文本“正在处理...”。

  6. 从工具箱的**“HTML”**选项卡,将 HtmlButton 控件添加到 UpdateProgress 控件,并将其 Value 属性设置为“取消”。

    UpdateProgress 教程

  7. 双击“刷新”按钮以便为其 Click 事件添加事件处理程序。

  8. 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();
    }
    
    Bb386518.alert_note(zh-cn,VS.90).gif说明:

    出于本教程的需要,Click 事件的处理程序有意引入了延迟。在实际应用中,您不会引入延迟。相反,延迟是由服务器通信量或需要花很长时间处理的服务器代码造成的,例如长时间运行的数据库查询。

  9. 在 <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 方法以停止异步回发。

  10. HtmlButton 控件的 onclick 属性设置为 CancelAsyncPostBack,即上一步中创建的处理程序的名称。

    <input id="Button2" 
           type="button" 
           value="cancel" 
           onclick="CancelAsyncPostBack()" />
    
    <input id="Button2" 
           type="button" 
           value="cancel" 
           onclick="CancelAsyncPostBack()" />
    
  11. 将下列样式块添加到 <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 控件。

  12. 保存更改,然后按 Ctrl+F5 在浏览器中查看页面。

  13. 单击“刷新”。

    经过短时间的延迟后,将显示进度消息。等待部分页更新完成,以便 UpdatePanel 控件中的消息变为显示时间。

    Bb386518.alert_note(zh-cn,VS.90).gif说明:

    通过设置 DisplayAfter 属性可以配置延迟的时间。默认值为 500 毫秒。

  14. 再次单击“刷新”,然后立即单击“取消”以停止部分页更新。

    请注意,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 控件

  1. 在前面创建的页中,切换到“设计”视图。

  2. 选择 UpdateProgress 控件,并在“属性”窗口中将 AssociatedUpdatePanelID 属性设置为 UpdatePanel1。

    UpdateProgress 教程

  3. Button 控件添加到 UpdatePanelUpdateProgress 控件外部的任一位置。

  4. 将按钮的 Text 属性设置为“触发器”,并将其 ID 设置为“Panel1Trigger”。

    UpdateProgress 教程

  5. 选择 UpdatePanel 控件,然后在“属性”窗口中单击 Triggers 属性框中的省略号 (…)。

    将显示**“UpdatePanelTrigger 集合编辑器”**对话框。

  6. 创建一个 AsyncPostBackTrigger 对象并将其 ControlID 属性设置为“Panel1Trigger”。

    UpdateProgress 教程

  7. 单击**“确定”**以关闭集合编辑器。

  8. 双击“触发器”按钮,以便为其 Click 事件添加事件处理程序。

  9. 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";
    }
    
  10. 在“源”视图中,将下列客户端脚本添加到页中已存在的 <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>
    
  11. 保存更改,然后按 Ctrl+F5 在浏览器中查看页面。

  12. 单击“刷新”按钮。

    经过短时间的延迟后,将显示进度消息。等待部分页完成更新,以便 UpdatePanel 控件中的消息显示时间。

  13. 单击“触发器”按钮。

    请注意,将显示进度消息。

    <%@ 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 控件。

请参见

概念

处理 PageRequestManager 事件

参考

Sys.WebForms.PageRequestManager 类