Understanding AJAX and ASP.NET
- 5/15/2010
Updating Progress
A recurring theme when programming any UI environment is keeping the user updated about the progress of a long-running operation. If you’re programming Windows Forms, you can use the BackgroundWorker component and show progress updating using the Progress control. Programming for the Web requires a slightly different strategy. ASP.NET AJAX support includes a component for this—the ASP.NET AJAX UpdateProgress control.
UpdateProgress controls display during asynchronous postbacks. All UpdateProgress controls on the page become visible when any UpdatePanel control triggers an asynchronous postback.
Here’s an exercise for using an UpdateProgress control on a page.
Using the UpdateProgress control
Add a new page to the AJAXORama site named UseUpdateProgressControl.aspx.
Drag a ScriptManager from the Toolbox onto the page.
Drag an UpdatePanel onto the page. Give the panel the ID UpdatePanelForProgress so that you can identify it later. Add the text This is from the update panel, and then add a Button to the update panel that will begin a long-running operation. Give it the ID ButtonLongOperation and the text Activate Long Operation.
Add a Click event handler for the button. The easiest way to create a long-running operation is to put the thread to sleep for a few seconds, as shown here. By introducing a long-running operation, you have a way to test the UpdateProgress control and see how it works when the request takes a long time to complete.
public partial class UseUpdateProgressControl : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { } protected void ButtonLongOperation_Click(object sender, EventArgs e) { // Put thread to sleep for five seconds System.Threading.Thread.Sleep(5000); } }
Now add an UpdateProgress control to the page. An UpdateProgress control must be tied to a specific UpdatePanel. Set the UpdateProgress control’s AssociatedUpdatePanelID property to the UpdatePanelForProgress panel you just added. Note that you can simply use the provided droplist to select this ID. Also change the DisplayAfter value to be 100 (indicating the progress indication should begin 100 milliseconds after the refresh begins).
Add a ProgressTemplate to the UpdateProgress control—this is where the content for the update display is declared. Add a Label to the ProgressTemplate so that you can see it when it appears on the page:
<asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanelForProgress" DisplayAfter="100"> <ProgressTemplate> <asp:Label ID="Label1" runat="server" Text="What's happening? This takes a long time..."> </asp:Label> </ProgressTemplate> </asp:UpdateProgress>
Run the page to see what happens. When you click the button that executes the long-running operation, you should see the UpdateProgress control show its content automatically. This graphic shows the UpdateProgress control in action:
Finally, no asynchronous progress updating UI technology is complete without a means to cancel the long-running operation. If you wish to cancel the long-running operation, you can do so by inserting a little of your own JavaScript into the page. You need to do this manually because there’s no support for this using the wizards. Write a client-side script block and place it near the top of the page—inside the <head> tag. The script block should get the instance of the Sys.WebForms.PageRequestManager. The PageRequestManager class is available to the client as part of the script injected by the ASP.NET AJAX server-side controls. The PageRequestManager has a method named get_isInAsyncPostBack() that you can use to figure out whether the page is in the middle of an asynchronous callback (generated by the UpdatePanel). If the page is in the middle of an asynchronous callback, use the PageRequestManager’s abortPostBack() method to quit the request. Add a Button to the ProgressTemplate and assign its OnClientClick property to make a call to your new abortAsyncPostback method. In addition to setting the OnClientClick property to the new abort method, insert return false; immediately after the call to the abort method, as shown in the following code. (Inserting return false; prevents the browser from issuing a postback.)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="UseUpdateProgressControl.aspx.cs" Inherits="UseUpdateProgressControl" %> <!DOCTYPE html PUBLIC "..."> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script type="text/javascript"> function abortAsyncPostback() { var obj = Sys.WebForms.PageRequestManager.getInstance(); if(obj.get_isInAsyncPostBack()) { obj.abortPostBack(); } } </script> </head> <body> <form id="form1" runat="server"> <div> <asp:ScriptManager ID="ScriptManager1" runat="server"> </asp:ScriptManager> </div> <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanelForProgress" DisplayAfter="100"> <ProgressTemplate> <asp:Label ID="Label1" runat="server" Text="What's happening? This takes a long time..."> </asp:Label> <asp:Button ID="Cancel" runat="server" OnClientClick="abortAsyncPostback(); return false;" Text="Cancel" /> </ProgressTemplate> </asp:UpdateProgress> <asp:UpdatePanel ID="UpdatePanelForProgress" runat="server"> <ContentTemplate> This is from the update panel <asp:Button ID="ButtonLongOperation" runat="server" onclick="ButtonLongOperation_Click" Text="Activate Long Operation" /> </ContentTemplate> </asp:UpdatePanel> </form> </body> </html>
ASP.NET AJAX support provides a great infrastructure for managing partial-page updates and for setting up other events such as regular timer ticks. The next section looks at the ASP.NET AJAX extender controls.