Join 149,460 VB.NET Programmers for FREE! Get instant access to thousands of VB.NET experts, tutorials, code snippets, and more! There are 2,107 people online right now. Registration is fast and FREE... Join Now!
I had this figured out once. But I am stumped again. I have a button on my main form that loads another form. It takes about 10 seconds for the Form2 to load up (It loads live weather data from the NET).
My problem is if I make the progress bar move, then the form2.show will not start till after the progress bar finishes. I need to somehow figure out the correct form event to trigger the bar and the childform to load simultaneously. I have included the button code and the timer code.. Thank you in advance for your help..
Brian --------------------------------------------------------------------------------------------------------------------------
CODE
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Me.SmoothProgressBar1.Value = 0
Me.Timer1.Interval = 1 Me.Timer1.Enabled = True
End Sub '-------------------------------------------------------------------------------------------------------------------------- Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
If (Me.SmoothProgressBar1.Value < 100) Then Me.SmoothProgressBar1.Value += 1 Else Me.Timer1.Enabled = False End If If SmoothProgressBar1.Value = 100 Then
CentralBC.Show() 'This Form I need to load while the prog bar is progressing, not afterward Me.Hide() 'I want to hide this form once CentralBC is loaded.. End If End Sub '-----------------------------------------------------------------------------------------
To show you how this works I have created a little demonstration. I have two forms, one called Form1 (creative I know) and another called (splash). In the form1_load event I have a loop that just loops 10,000 times. Normally when you launch this form from the splash page, it would freeze the progress bar until the form is loaded. By adding DoEvents() to the for loop, we allow our application to handle other events taking place like the progress bar incrementing.
Splash page...
CODE
Public Class splash
Private Sub splash_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Timer1.Start() End Sub
' Timer tick event, increments the progress bar 1 every 200 milliseconds. Once it is finished, disable ' the timer and hide the form. ' If the progress bar is at a value of 10, lets launch our form.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick If (Me.ProgressBar1.Value < 100) Then Me.ProgressBar1.Value += 1 Else Me.Timer1.Enabled = False Me.Hide() End If
If (Me.ProgressBar1.Value = 10) Then Dim frm As New Form1 frm.Show() End If End Sub End Class
As you can see from this code, our splash page launches and starts a timer that executes every 200 milliseconds. When the progress bar is at a value of 10, we launch our form which has a huge loop in it. Normally this would pause the progress bar until the form loads. So lets add DoEvents!
Form1....
CODE
Public Class Form1
' Form load, creates a huge loop. But since we have DoEvents(), it will allow the app to handle ' other events like incrementing that progress bar on the timer tick event back over in the splash page.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim i As Integer = 0
For i = 0 To 10000 ' Tell the app to allow other events to fire during process of loop System.Windows.Forms.Application.DoEvents() Debug.Print("I is: " & i.ToString()) Next End Sub
End Class
Typically you would want the progress bar to pause if it is loading a form because it makes no sense to have the progress bar say that it is 50% complete on loading when it hasn't even loaded the first form in a 10 form series. It is often better to increment the progress bar after each item is loaded and increment it by a block of progress rather than by 1%. With this you will find that you will have to time it so that progress bar reads 10% when the first of ten forms is completed rather than incrementing the progress bar 10% after the first form is loaded, increment by another 10% after the second form is loaded etc.
But do what is needed. I have provided the tool above to show you how it works. Enjoy!
I have added System.Windows.Forms.Application.DoEvents() in 5 different places on my main form
But, as soon at the counter hits 10, the bar freezes until the form is loaded
When my mainform loads, it immediately goes to a sub in a module and loads a data stream and reads it into a long string builder. Its not a loop structure like your example because its streaming data from a web site.
It reads 600,000 chars into the string builder which takes about 20sec. to download. I wonder if I am going to have to implement this differently?
Wonder if i could capture the stream position in the file and apply that to the progress bar?
I am so sad now.. back to square one with this..But at least you got my progress bar to 10%, only 90% to go
Most of the time you will want to loop through a stream rather than trying to suck across such a big chunk of data. I would recommend going with a looping situation and then you can use the DoEvents() setup. Not only that but yeah you can hook the progress bar to this loop to give up to the second feedback of where in the website streaming process you are. But first focus on getting the loop setup and reading through the stream and to work with your progress bar before tackling the progress bar mirroring your progress.
The data stream is held in a string called "data" and is shared with 36 other forms.
Do you have any idea how I can change this to loop the data stream into the string builder
right now data = reader.ReadToEnd() is the block method used. I will do whatever it take to learn this .. I love programming..But hate my lack of knowledge...
Hopefully this post can lead to an answer.
CODE
Sub DownloadPageOregon()
Dim uri As New Uri("http://www.met.utah.edu/cgi-bin/droman/raws_ca_monitor.cgi?state=OR&rawsflag=290") Dim builder As New StringBuilder
Dim request As WebRequest = WebRequest.Create(uri) Dim response As WebResponse = request.GetResponse() builder = New StringBuilder builder.Append("Request type: " & request.GetType().ToString() & vbCrLf) builder.Append("Response type: " & response.GetType().ToString() & vbCrLf) builder.Append("Content length: " & response.ContentLength & _ " bytes" & vbCrLf) builder.Append("Content type: " & response.ContentType & vbCrLf) 'MsgBox(builder.ToString())
Dim stream As Stream = response.GetResponseStream() Dim reader As New StreamReader(stream) System.Windows.Forms.Application.DoEvents() [b] data = reader.ReadToEnd()[/b] reader.Close() stream.Close() End Sub
This post has been edited by Schmit38: 22 Jan, 2008 - 02:11 PM
Typically you put this right in a loop that is going to cause the freeze. So if you have a loop in your DownloadPageOregon() sub where it would cause a freeze (like reading the stream) and put it right before it (that is, right before where you read the stream itself in the loop). Try putting it on the line before you open the connection to pull the data from the site.
This post has been edited by Martyr2: 22 Jan, 2008 - 02:06 PM
Ahhh I see, your webresponse and webrequest setup is the one that is going to be causing the problem here. Here is an example of going to a full thread setup where we run your download page sub routine on its own thread.
CODE
Public Class Form1 ' Create a thread variable for the form Private DownloadPageThread As Thread
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
' Create a new thread and give it the address of the sub routine on this form ' Set it to being in the background ' Then start the thread.
DownloadPageThread = New Thread(AddressOf Me.DownloadPageOregon) DownloadPageThread.IsBackground = True DownloadPageThread.Start() End Sub
Private Sub DownloadPageOregon()
Dim uri As New Uri("http://www.met.utah.edu/cgi-bin/droman/raws_ca_monitor.cgi?state=OR&rawsflag=290") Dim builder As New StringBuilder
Dim request As WebRequest = WebRequest.Create(uri) Dim response As WebResponse = request.GetResponse() builder = New StringBuilder builder.Append("Request type: " & request.GetType().ToString() & vbCrLf) builder.Append("Response type: " & response.GetType().ToString() & vbCrLf) builder.Append("Content length: " & response.ContentLength & _ " bytes" & vbCrLf) builder.Append("Content type: " & response.ContentType & vbCrLf)
Dim stream As Stream = response.GetResponseStream() Dim reader As New StreamReader(stream)
' Do whatever you need to do with the content, here we are printing to debug screen Debug.Print(reader.ReadToEnd())
' Dont forget to close your webresponse object response.Close() reader.Close() stream.Close() End Sub End Class
With this setup you will be putting this routine in a background thread which will go out and fetch the content for you without freezing your interface and progress bar. You can make the thread sleep afterwards or abort it or whatever. You might want to make it sleep so you can wake it up later in the program and fetch updated weather conditions from the site.