Introduction
In this short article, I will explain how to create a progress bar for ASP.NET websites. In order to update the progress bar, I'm using an AJAX UpdatePanel
and the Timer
control.
The controls (Default.aspx)
First of all, I created an AJAX enabled website project and dropped some controls on the web form. Here is the resulting Default.aspx page:
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="Default.aspx.vb" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<atlas:ScriptManager ID="ScriptManager1"
runat="server" EnablePartialRendering="True" />
<div>
<atlas:TimerControl ID="TimerControl1" runat="server"
OnTick="TimerControl1_Tick" Enabled=false Interval=2000>
</atlas:TimerControl>
</div>
<atlas:UpdatePanel ID="UpdatePanel1" runat="server" Mode="Conditional">
<Triggers>
<atlas:ControlEventTrigger ControlID=TimerControl1 EventName=Tick />
</Triggers>
<ContentTemplate>
<div style="background-color:Black; height:10px; width:300px">
<div id="bar" runat="server"
style="height:10px; width:0px; background-color:Fuchsia">
</div>
</div>
<asp:Label ID="Label1" runat="server" Text="0 %"></asp:Label>
<br />
<br />
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl="~/Default.aspx"
Visible="False">Reload Page</asp:HyperLink><br />
</ContentTemplate>
</atlas:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Button" />
</form>
<script type="text/xml-script">
<page xmlns:script="http://schemas.microsoft.com/xml-script/2005">
<references>
</references>
<components>
</components>
</page>
</script>
</body>
</html>
Here are some details about the above code. To update the progress bar, I used an AJAX Timer
control. This timer calls the server method TimerControl1_Tick
. TimerControl1
has to be disabled at first.
<atlas:TimerControl ID="TimerControl1" runat="server"
OnTick="TimerControl1_Tick" Enabled=false Interval=2000>
</atlas:TimerControl>
Then I created an UpdatePanel
that is triggered by the TimerControl1
tick event. This means whenever the tick event of TimerControl1
fires, UpdatePanel1
will be refreshed:
<atlas:UpdatePanel ID="UpdatePanel1" runat="server" Mode="Conditional">
<Triggers>
<atlas:ControlEventTrigger ControlID=TimerControl1 EventName=Tick />
</Triggers>
<ContentTemplate>
</ContentTemplate>
</atlas:UpdatePanel>
Last, I used two div
-elements to display the progress bar:
<div style="background-color:Black; height:10px; width:300px">
<div id="bar" runat="server" style="height:10px; width:0px; background-color:Fuchsia">
</div>
</div>
Next, I placed a Button
outside the UpdatePanel1
to submit the form and start the long running task:
<asp:Button ID="Button1" runat="server" Text="Button" />
The code (Default.aspx.vb)
When the user clicks Button1
, the form is posted to the server. Then the code-behind creates a new thread to execute the long running task. Next, I start the thread and enable TimerControl1
.
Protected Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
Session.Add("status", 0)
Dim objThread As New Thread(New System.Threading.ThreadStart(AddressOf DoTheWork))
objThread.IsBackground = True
objThread.Start()
Session("Thread") = objThread
Button1.Enabled = False
TimerControl1.Enabled = True
End Sub
The long running task is done in the function DoTheWork
. Here is the code:
Protected Sub DoTheWork()
Dim i As Integer = 0
While i < 100
Thread.Sleep(500)
i = i + 1
Session("status") = i
End While
Dim objThread As Thread = CType(Session("Thread"), Thread)
objThread.Abort()
End Sub
The current status of the task is written into a session variable status
. This session variable will be used in the TimerControl1_Tick
event to update the progress bar. Here is the code for the tick event:
Protected Sub TimerControl1_Tick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles TimerControl1.Tick
Dim i As Integer = CType(Session.Item("status"), Integer)
If i = 100 Then
TimerControl1.Enabled = False
HyperLink1.Visible = True
End If
Label1.Text = i.ToString + " %"
Dim div As HtmlGenericControl = Me.FindControl("bar")
i = i * 3
div.Style.Item("width") = i.ToString + "px"
End Sub
First, I convert the session variable status
into an Integer
. Next, I check whether the task is finished (i=100
). When this is true, I disable TimerControl1
again and enable a hyperlink to reload the page. In any case, I update the text value for Label1
. And, I also set the width for the inner div
-element.