Introduction – What is the ASP.NET UpdateProgress Control?
The UpdateProgress control is a very handy control meant for use in conjunction with an ASP.NET UpdatePanel. The UpdatePanel is an Ajax control that makes it very easy to update part of a page using an Ajax postback rather than a full postback.
This avoids page flicker and also leaves the page not in a postback state, that is, a subsequent refresh of the browser won’t force a postback. The UpdateProgress control is designed to make it easy to show some markup while the update is happening to give the user a visible cue that something is happening.

So a typical trick is to show an animated working indicator something like this So you would add the UpdateProgress control inside the UpdatePanel something like this:
<asp:Button ID="btnSavePreferences" runat="server" />
<asp:UpdateProgress ID="progress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1">
<ProgressTemplate>
<img src='<%= Page.ResolveUrl("~/Data/SiteImages/indicators/indicator1.gif") %>' alt=' ' />
</ProgressTemplate>
</asp:UpdateProgress>
Check out some of our other guides:
The Problem – Block Rendering instead of Inline Rendering
The problem is that the UpdateProgress control renders as a div element which is a block element rather than an inline element, so instead of rendering the indicator right next to your button, it renders it below your button on a new line. In some cases that may be ok, but if you really want the indicator to just be right next to the button it’s a problem.
I came across this situation recently in my work on mojoPortal and I really wanted to show the indicator in the same line as the button, it gave a bad effect for the indicator to jump below the button.
So I did some searching on the internet and found a number of people complaining about this problem and a few less than satisfactory suggestions for solving it.
• A post on the ASP.NET Forums
• ASP.NET Resources post – suggested a way to make it render in the middle rather than below but not really what I was after.
• The last comment on the above post suggested using Important in the CSS to force inline rendering.
I’m not sure if that really works because the javascript associated with the UpdateProgress sets it to block when it shows the content. Also, the !Important is not used by IE 6 unless in standards-compliant mode which is not the default and not commonly used in IE 6.
James Van Klink suggested another solution, wrapping the UpdateProgress inside a span and using absolute positioning on the span. However this produces invalid markup, you are not supposed to nest block elements inside inline elements.
Another solution was posted on stackoverlfow.com, but it seems less elegant than I would like.
So, in summary, the problem is that it renders as a div which is a block element, and the javascript associated with the control changes from display:none; to display:block when the UpdatePanel is updating.
The Solution- Borrow The UpdateProgress control from the Mono Project and modify it.
What I really wanted was to make the UpdateProgress control render as a span which is an inline element and I wanted the javascript to toggle between display:none; and display:inline;. Often, when I face a situation where an ASP.NET control cannot be coerced into rendering or behaving as I would like, I have found that I can borrow the Mono Project implementation of the ASP.NET control and modify it to meet my needs.
Sometimes it’s more difficult than others to use this approach depending on what mono internals it may be using, but in this case, it was fairly easy.
First I grabbed the UpdateProgress.cs from the Mono source code and added it to my project as UpdateProgressSpan.cs and changed the namespace to match my own project. Then it was fairly simple to change the rendering to use a span instead of a div.
However, the problem still remained that the javascript would set the display to block which would still make the span render as a block just like a div. So I scrounged around in the javascript for Ms. Ajax and found the relevant part for UpdateProgress. I copied it into my own javascript file, changed the namespace, and modified it to use display:inline instead of display:block.
The only changes I had to make in my UpdateProgressSpan.cs were:In OnPreRender I had to tell it about my javascript like this:
ScriptReference SRef = new ScriptReference();
SRef.Path = "~/ClientScript/ajaxupdateprogressspan.js";
ScriptManager.Scripts.Add(SRef);
ScriptManager.RegisterScriptControl(this);
In Render, I changed it to use Span instead of div and use inline instead of block.
In the GetScriptDescriptors method, I changed it from referencing the original MS Ajax to use my custom one like this:
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("mojo._UpdateProgress", this.ClientID);
Finally, in my page, I used my custom control instead of the ASP.NET version like this:
<asp:Button ID="btnSavePreferences" runat="server" />
<portal:UpdateProgressSpan ID="UpdateProgress2" runat="server" AssociatedUpdatePanelID="UpdatePanel1" >
<ProgressTemplate>
<img src='<%= Page.ResolveUrl("~/Data/SiteImages/indicators/indicator1.gif") %>' alt=' ' />
</ProgressTemplate>
</portal:UpdateProgressSpan>
Problem solved, the working indicator displays right next to the button.