telemaco10399
telemaco10399

Reputation: 39

Progress bar gets stuck at 100%

I've programmed a "Please wait" form in which I inserted a progress bar. I looked around how to program a progress bar and this is what I did. First of all I programmed the button - Button3_Click - I press to start. Then I programmed the timer - Timer1_Tick -and so I wrote:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Timer1.Enabled = True
    Timer1.Interval = 50
    Timer1.Start()
    
*[calculus code]*

If Form18.ProgressBar1.Value = 100 Then
    Form18.Hide()
    hrrspkexcel.Visible = True
End If

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
iProgressBarValue += 1
Select Case iProgressBarValue
    Case 1, 3, 5, 7, 9
        Form18.ProgressBar1.ForeColor = Color.White
        Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
        Form18.ProgressBar1.Value = (iProgressBarValue * 10)
    Case 2, 4, 6, 8
        Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
        Form18.ProgressBar1.Value = (iProgressBarValue * 10)
    Case 10
        Form18.ProgressBar1.Value = (iProgressBarValue * 10)
        Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
        Timer1.Stop()
        Timer1.Enabled = False
End Select
End Sub

I can't understand why the progress bar gets stuck at 100% and neither form18 gets hidden, nor hrrspkexcel becomes visible. Where am I doing wrong? Thanks for any support. Best regards.

Edit: I tried to edit my code as comments say:

    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Timer1.Enabled = True
        Timer1.Interval = 50
        Timer1.Start()
[calculus code]
        iProgressBarValue += 1
        Select Case iProgressBarValue
            Case 1, 3, 5, 7, 9
                Form18.ProgressBar1.ForeColor = Color.White
                Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
                Form18.ProgressBar1.Value = (iProgressBarValue * 10)
            Case 2, 4, 6, 8
                Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
                Form18.ProgressBar1.Value = (iProgressBarValue * 10)
            Case 10
                Form18.ProgressBar1.Value = (iProgressBarValue * 10)
                Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
                Timer1.Stop()
                Timer1.Enabled = False
        End Select
        If Form18.ProgressBar1.Value = 100 Then
            Form18.Hide()
            hrrspkexcel.Visible = True
        End If
End Sub
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        If Form18.ProgressBar1.Value = 100 Then
            Timer1.Stop()
            Timer1.Enabled = False
        End If
    End Sub

In this case, progress bar gets stuck at 10%.

Edit II: Following suggestions in comment, I removed the timer and based my progress bar on the entity of the calculus code (Form18.ProgressBar1.Maximum). Anyway, what is reported under [calculus code] is an heavy Excel export so the progress bar freezes to 0% until exportation has ended and then start running (I set loading cursor to understand when exportation has ended), so maybe I'd need of a BackgroundWorker to make my bar progressing while exporting? (I'm a beginner programmer and I read somewhere something about this, but I don't know if this solution is suitable for me, so I'm asking).

At last, this is how I corrected my code:

Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Form18.ProgressBar1.Minimum = 0
    Form18.ProgressBar1.Value = 0
    Form18.ProgressBar1.Maximum = [if loop criteria based on my code]
    Form18.ProgressBar1.Increment(1)
    Form18.Show()
    
    [calculus code - excel export]
    
    If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
        Form18.Hide()
        hrrspkexcel.Visible = True
    End If
End Sub

With this edit, my ProgressBar freezes at 0% even if exportation has already ended, so I'm obviously doing wrong somewhere. Thanks for all the support you're giving to me.


Edit III: I managed in making progressbar working using a for loop to increment its value, as you suggested me, with a proportional equation to percentage and to overcome the problem about the maximum value of the bar, that's always set on 100. So thanks all of you for your support. The last thing I want to ask you - if I'm not offtopic - is how to make my loading form - with the progressbar - on foreground and to "lock" interaction with all other forms.


Edit III BIS: I've tried to use Backgroundworker in order to overcome the loading-form freezing. This is the first time I'm using this command and I don't know if it's the right way to make it comunicating to a ShowDialog Form. This is what I wrote:

Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
    Form18.ProgressBar1.Minimum = 0
    Form18.ProgressBar1.Value = 0
    BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Form18.ShowDialog()
[excel calculus export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
    Form18.Hide()
    hrrnativexcel.Visible = True
End If
End Sub

I'm always getting the same trouble: when Form18 appears, remains on 0% loading.


Edit IV: I'm having an issue about progressbar increment for the following situation: I have two for loops for exporting values in excel and the upper bound of this loops are different. So I've created a third for loop, whose upper bound is the sum of the upper bounds of the two abovementioned for loops, in order to increment the progressbar progress. When it reaches 100%, it starts again going in loop. How could I solve this issue? Here is the code I'm using:

For i = 1 To CInt(Form6.ListBox1.Items.Count)
    For j = 1 To CInt(Form10.ListBox1.Items.Count)
        For k = 0 To CInt(CInt(Form6.ListBox1.Items.Count) + CInt(Form10.ListBox1.Items.Count))
            hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
            hrrspkexcel.Cells(i + 1, 2).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
            Form18.ProgressBar1.Value = CInt(100 * k / (CInt(Form6.Label9.Text) + CInt(Form10.ListBox1.Items.Count)))
            Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
        Next
    Next
Next

Thanks in advance.


Edit V: I've updated my code following comments in order to solve the issue described in Edit IV. This is what I wrote:

Dim pbloop As Integer
pbloop = CInt(Form10.ListBox1.Items.Count) * CInt(Form6.ListBox1.Items.Count)
For p = 1 To pbloop
    For i = 1 To CInt(Form6.ListBox1.Items.Count)
        For j = 1 To CInt(Form10.ListBox1.Items.Count)
            hrrspkexcel.Cells(i + 1, 4).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
            hrrspkexcel.Cells(i + 1, 3).value = Form6.ListBox2.Items(CInt(i + 1) - 2)
            hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox1.Items(CInt(j + 1) - 2)
            hrrspkexcel.Cells(j + 1, 2).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
            Form18.ProgressBar1.Value = CInt(100 * p / pbloop)
            Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
        Next
    Next

I'm getting stuck always at 0% and progress bar that doesn't increase.

Upvotes: 0

Views: 1056

Answers (3)

SteveCinq
SteveCinq

Reputation: 1963

You current code reads as if you want the Progress Bar to update on a button click a maximum of 10 times before hiding the form. Is that your intention? I would have expected that you want the "Please wait ..." form to stay visible with the progress bar updating every, say, second, then disappear?

Using a timer for the latter is fine but for the former, you can simply update the progress bar directly - as you are doing - without a timer.

Also, you don't need to multiply your progress bar value by 10; you can simply set the progress bar Maximum value to 10.

Also, since you change the ForeColor value on the first click, you can probably dispense with the Case Select {even|odd} test because the code is otherwise identical.

So without the timer or the color change and with Progress Bar Maximum = 10, all you need to do is:

Form18.ProgressBar1.Value = iProgressBarValue
Form18.Label3.Text = $"{iProgressBarValue} %")

No need for the Case Select.

Another option for the PB is to use the PerformStep() method to increment it. Just set the Step property to 1 for this approach.

Upvotes: 1

Idle_Mind
Idle_Mind

Reputation: 39122

Try something more like this out:

Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
    Button3.Enabled = False
    hrrspkexcel.Visible = False ' changed this to a Label next to the button just for demonstration

    Dim f18 As New Form18
    f18.ProgressBar1.Minimum = 0
    f18.ProgressBar1.Value = 0
    f18.ProgressBar1.Maximum = 100 ' <-- leave the maximum at 100!
    f18.Show(Me)

    Dim pct As Integer
    Dim maximum As Integer = 319 ' <-- figure out the max value based on your "calculus code"

    Await Task.Run(Sub()
                       ' [calculus code - excel export]
                       For i As Integer = 0 To maximum
                           System.Threading.Thread.Sleep(50) ' <- some kind of processing going on

                           ' calculate the percentage based on your loop value "i" and the "maximum":
                           pct = CDbl(i) / CDbl(maximum) * 100 ' <-- scale your loop value to 100
                           Try
                               f18.ProgressBar1.Invoke(Sub()
                                                           f18.ProgressBar1.Value = pct
                                                       End Sub)
                           Catch ex As Exception
                               ' User closed the progressform, create another one
                               Me.Invoke(Sub()
                                             f18 = New Form18
                                             f18.ProgressBar1.Minimum = 0
                                             f18.ProgressBar1.Value = 0
                                             f18.ProgressBar1.Maximum = 100 ' <-- leave it at 100
                                             f18.Show(Me)
                                             ' make progressbar immediately jump to the right spot
                                             f18.ProgressBar1.Value = f18.ProgressBar1.Maximum
                                             f18.ProgressBar1.Value = pct
                                         End Sub)
                           End Try
                       Next
                   End Sub)

    ' when we hit here, the "calculus code" above completed
    f18.Close()
    hrrspkexcel.Visible = True ' changed this to a Label next to the button just for demonstration
    Button3.Enabled = True
End Sub

Here's what it looks like in action:

enter image description here

Upvotes: 1

UserNam3
UserNam3

Reputation: 655

This is not the true answer of the problem but a sample to show you how to use a progress bar.

This code is not beautiful, I know, it's for the example. Please be careful when you use a textbox text as a number without check what is written.

enter image description here



Imports System.Threading

Public Class Form1


    Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click


        ' Initialisation of the progressbar
        myProgressbar.Value = 0
        myProgressbar.Maximum = tbxTo.Text

        lbxInfos.Items.Clear() ' Clear the content in the listbox1 if it's not the first run


        ' This simulate your [calculus code], I just add an information in the listbox
        For i As Integer = tbxFrom.Text To tbxTo.Text

            myProgressbar.Value = i ' Set the progressbar avancement

            lbxInfos.Items.Add("This is the loop n° " & i & " !")

            lbxInfos.Refresh() ' Just because the listbox will not be refresh until the end of the sub
            Thread.Sleep(200) ' The code is too fast, I add this to see the progress (= wait 200 ms)
        Next

        MsgBox("This is the end ! Now the form will be closed")

        Me.Close()

    End Sub



End Class

Upvotes: 1

Related Questions