Problem with running a Progress Bar...

G

Guest

Hi all,

I am running a VS 2003 .NET project on my client machine (Win 2000 SP4,
..NET framework 1.1), running an ASP.NET application on a remote web server
(Win 2000 Server, IIS 6.0, .NET framework 1.1).
The application implements a Progress Bar webcontrol, that pops up in a
window, using the HttpHandler interface, on the event of a button click. The
handler's process request routine reads the status of the progress by
querying the Application-state.
When I am on the webpage and click the button the first time around, the
progress bar comes up and displays correctly. The problem is that, on
subsequent tries, I can see the pop-up window come up and then it disappears
quickly. I haven't been able to solve this issue.

Here is the breakdown of the code:


1) The following VB class implements the HttpHandler class and a Webcontrol:

Imports System
Imports System.IO
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.ComponentModel

Namespace Progress

Public Class CHttpUploadHandler
Implements IHttpHandler

Public Sub CHttpUploadHandler()
'
' TODO: Add constructor logic here
'
End Sub

Public ReadOnly Property IsReusable() As Boolean Implements
System.Web.IHttpHandler.IsReusable
Get
Return True
End Get
End Property

Public Sub ProcessRequest(ByVal context As System.Web.HttpContext)
Implements System.Web.IHttpHandler.ProcessRequest
Dim writer As HtmlTextWriter = New
HtmlTextWriter(context.Response.Output)

' Build the HTML for the popup
writer.WriteFullBeginTag("html")
writer.WriteFullBeginTag("body")
writer.WriteFullBeginTag("head")
writer.WriteFullBeginTag("title")
writer.Write("Progress")
writer.WriteEndTag("title")
writer.WriteBeginTag("meta")
writer.WriteAttribute("http-equiv", "refresh")
writer.WriteAttribute("content", "1")
writer.Write(HtmlTextWriter.TagRightChar)
writer.WriteEndTag("head")
writer.WriteFullBeginTag("body")

Dim progress As Integer

' When the process is unknown in the Application-state, the
process is 0
If IsDBNull(context.Application("progress_" +
context.Request.Params("id"))) Then
progress = 0
Else
' Else this equals the int in the Application-state
progress = CInt(context.Application("progress_" +
context.Request.Params("id")))
End If

' Create the progressbar
Dim pbProgress As Progress.ProgressInfo = New
Progress.ProgressInfo
pbProgress.ID = "ProgressBar"

' Set the value of the progressbar
pbProgress.PercentageOfProgress = progress
pbProgress.GenerateTable(writer)

writer.Write("<div align=" + Chr(34) + "center" + Chr(34) + ">"
+ CStr(progress) + "%</div>")

' If the process is finished
If progress = 100 Then
' Close the popup-window using JavaScript
writer.WriteBeginTag("script")
writer.WriteAttribute("language", "javascript")
writer.Write(HtmlTextWriter.TagRightChar)
writer.Write("window.close();")
writer.WriteEndTag("script")

' DON'T FORGET to remove the variable from the
Application-state, otherwise it will exist 'forever'
context.Application.Remove("progress_" +
context.Request.Params("id"))
End If

writer.WriteEndTag("body")
writer.WriteEndTag("html")
End Sub

End Class

Public Class ProgressInfo
Inherits WebControl
Implements INamingContainer

' Member variables
Private nProgress As Integer = 0
Private nPercentOfProgress As Integer = 0

' <summary>
'Default Constructor
'</summary>
Public Sub ProgressInfo()
' Set the default colors of the control
Me.BackColor = System.Drawing.Color.LightGray
Me.ForeColor = System.Drawing.Color.Blue
End Sub

' <summary>
' Accessor to set the background color of the control
' </summary>
Public Overrides Property BackColor() As System.Drawing.Color
Get
Return MyBase.BackColor
End Get
Set(ByVal Value As System.Drawing.Color)
MyBase.BackColor = Value
End Set
End Property

' <summary>
' Accessor to set the foreground color of the control
' </summary>
Public Overrides Property ForeColor() As System.Drawing.Color
Get
Return MyBase.ForeColor
End Get
Set(ByVal Value As System.Drawing.Color)
MyBase.ForeColor = Value
End Set
End Property

' <summary>
' Accessor to update the progress of the control
' </summary>
Public Property PercentageOfProgress() As Integer
Get
Return nProgress
End Get
Set(ByVal Value As Integer)
If Value > 100 Then
nProgress = 100
ElseIf Value < 0 Then
nProgress = 0
Else
nProgress = Value
End If
' Calculate the percentage done if the progress > 0
If nProgress <> 0 Then
nPercentOfProgress = nProgress / 5
End If
End Set
End Property

' <summary>
' Renders the progress bar
' </summary>
Public Sub GenerateTable(ByVal output As HtmlTextWriter)
' 09/29/2006 DX Added this routine to render the progress bar,
rewrote original which did not work.
Dim TableString As String

TableString = "<div align=center><TABLE cellpadding=0
cellspacing=0 border=1 width=100>"
TableString = TableString + "<TR>"

' Since we split the data into 20ths
' we need a cell for each piece.
For i As Integer = 0 To 19
' If the count is less then the percent done
' then you need to set it to the fore color.
' Otherwise the progress has not reached this
' cell and you need to set it to the back color.
If i < nPercentOfProgress Then
TableString = TableString + "<TD width=5 height=16
bgcolor=blue> </TD>"
Else
TableString = TableString + "<TD width=5 height=16
bgcolor=white> </TD>"
End If
Next
' Output the string to the web page
TableString = TableString + "</TR></TABLE></div>"
output.Write(TableString)
End Sub

End Class

End Namespace


2) This webpage is where the Progress Bar control gets loaded and the window
pops up:

<%@ Page Language="vb" AutoEventWireup="false"
Codebehind="ProgressBar.aspx.vb" Inherits="odm.ProgressBar"%>
<%@ Register TagPrefix="PB" Namespace="Progress" Assembly="Progress"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>ProgressBar</title>
<meta content="Microsoft Visual Studio .NET 7.1" name="GENERATOR">
<meta content="Visual Basic .NET 7.1" name="CODE_LANGUAGE">
<meta content="JavaScript" name="vs_defaultClientScript">
<meta content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<PB:progress id="ProgressBar" Runat="server"></PB:progress>
</form>
</body>
</HTML>


3) In the web.config file, I added the following setting under the
<system.web> tag:

<httpHandlers>
<add verb="GET" path="ProgressBar.aspx"
type="Progress.Progress.CHttpUploadHandler, Progress" validate="false" />
</httpHandlers>


4) On the webpage where I click the button to pop-up the Progress bar
window, here's the code-behind for the Button click event. Please note that I
update the progress counter each time I execute some code to do a task
(Create IO directory, render a PDF file through WSDL, or run a shell command).

Private Sub ButtonRender_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ButtonRender.Click

' Start the process
Dim i As Integer
Dim Interval, Increment As Integer

' DX 10/05/2006 Initialize start value for progress bar and
calculate increment
Increment = CInt(Math.Round(100 / (CInt(TextBox3.Text) + 1)))
Interval = 0
Application("progress_" + Session.SessionID) = Interval
' 01/05/2006 DX Check for existing sub-directory, if not, create one
for path of file dump
If Not IO.Directory.Exists(Session("UserDir")) Then
IO.Directory.CreateDirectory(Session("UserDir"))
' Save the progress in the Application-state with a unique key
for this session
Interval += Increment
Application("progress_" + Session.SessionID) = Interval
End If
For i = 1 To CBListReports.Items.Count()
If CBListReports.Items(i - 1).Selected Then
Select Case CBListReports.Items(i - 1).Value
Case "BoardofDirectors" '"Agency Budget",
Interval += Increment
Application("progress_" + Session.SessionID) =
Interval
RenderReport(CBListReports.Items(i - 1).Value)
Case Else
Interval += Increment
Application("progress_" + Session.SessionID) =
Interval
RenderReportOneParameter(CBListReports.Items(i -
1).Value)
End Select
End If
Next
Interval += Increment
If Interval > 100 Then
Interval = 100
End If
Application("progress_" + Session.SessionID) = Interval
' 1-20-2006 DX Call subroutine to form arguments parameter for call
to start process
MergeIntoOnePDF()
System.Threading.Thread.Sleep(1000)
Interval = 100
Application("progress_" + Session.SessionID) = Interval
Interval = 0
End Sub


5) In the Page_Load routine of the previous webpage, I have this line of code:

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not Page.IsPostBack Then
....
ButtonRender.Attributes.Add("OnClick", "StartProcess('" +
Session.SessionID.ToString() + "');")
....
End If
End Sub


6) Here is the javascript code that calls the pop-up window and passes the
session id information for the Application-state.

<script language="JavaScript" type="text/javascript">
function StartProcess(id)
{
var features;
features =
"toolbar=no,directories=no,menubar=no,scrollbars=no,resizable=no,height=100,width=200";
window.open('ProgressBar.aspx?id=' + id, 'Progress', features);
}
 
G

Guest

Well, I managed to solve this problem. It took me a while but the solution
was to add a conditional statement in the code-behind for the button click
event on the webpage that calls the pop-up window where the progress bar
shows up. The conditional statement is placed towards the end of the code in
the subroutine:

Private Sub ButtonRender_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles ButtonRender.Click
....
MergeIntoOnePDF()
If progress <> 100 Then
System.Threading.Thread.Sleep(1000)
Interval = 100
Application("progress_" + Session.SessionID) = Interval
Interval = 0
End If
End Sub
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,025
Latest member
KetoRushACVFitness

Latest Threads

Top