Question Updating Progressbar within a class

Greedyh4mster

Member
Joined
Aug 12, 2010
Messages
6
Programming Experience
Beginner
Hiya!

I am wondering how do I update a Progress Bar that resides in Form1 (for example) from a newly created class called from the Button in Form1.

I have read several tutorial about backgroundworker. Most of the googled tutorials have their "long process code" in the do_work event. I have tried them and got it working from within the form itself.

However, there are 2 parts (long process) in which I wish to incorporate the updating of the progress bar; First one being a long sub routine that is in the main form (Form1). The second one is another long processing function that resides in a class. It is the second one that is giving the problem as I have no idea how to call the backgroundworker.reportProgress() to update the UI.

Here is the sample flowchart that I have created for the second long processing function:

24blqol.jpg


I wish to insert a new instruction that says "Update the Progress bar that is in Form1" after the current instruction "Store the member into a collection".

Is there anyone who can point me to the correct direction of implementing it? :)
 
You add Progress event to your class, let consumer (form) subscribe to it.
How to: Add Events to a Class
How to: Raise an Event (Visual Basic)

Your class that uses BackgroundWorker can subscribe to its events and relay them through its own events.

Thank you for replying me so fast! :D

I have tried out your solution but I am not very sure whether am I doing the correct implementation. So would you kindly help me out with it?

Database Class:
VB.NET:
Public Class Database
    Public Event progress(ByVal value As Integer)
    
    Public Function getMembers() as boolean
        'Fetching from database
        'Reading the rows
        While reader.read
            'Create new member and add to collection
            RaiseEvents progress(10)
        End While
    End Function
End Class

Form1:
VB.NET:
Private WithEvents bgthread As System.ComponentModel.BackgroundWorker

Private Sub bgthread_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgthread.DoWork
        getMembers()
End Sub

Private Delegate Sub sub_progress_handler(ByVal value As Integer)

Private Sub progress_handler(ByVal value As Integer)
    If InvokeRequired Then
        Me.Invoke(New sub_progress_handler(AddressOf progress_handler), value)
    End If
    ProgressBar1.Value = value
    ProgressBar1.Refresh()
End Sub

Private sub getMembers()
    Using db as New Database
        If db.connect Then
            AddHandler db.progress, AddressOf progress_handler
            db.getMembers()
        End If
    End Using
End Sub

The above are the sample codes that I have extracted from my main application. It works momentarily; I can see the progress bar is updated. But after 2 bars (meaning the raiseevent is raised 2 times), I received a FormatException.

It occurred in this line:
VB.NET:
Me.Invoke(New sub_progress_handler(AddressOf progress_handler), value)

When I checked the value of $value; It was an integer containing a value of 10. Therefore, I have no idea how come there was a FormatException. :confused:
 
Firstly "While reader.read"? There is no determined progress information available when doing this, so I don't see the need for a progress event, you should use marquee style progress for such stuff.

About the code you posted, that is actually a cross between what I meant and a different approach possible, and I would not do it like that, but suggest one of these two approaches (pseudo code), depending on how interlinked you want to design the class.
  • similar to yours, but using bgworker for what its worth:
    VB.NET:
    class form
    
    sub dowork()
       bgworker.runworkerasync
    end sub
    
    withevents bgworker
    
    sub bgworker_progress() handles bgworker.progress
       me.progressbar.value = e.progresspercent
    end sub
    
    sub bgworker_dowork() handles bgworker.dowork
       dim db as new DB
       db.bgworker = me.bgworker
       db.dowork
    end sub
    
    end class
    VB.NET:
    class DB
    field bgworker 'passed from form
    
    sub dowork
       do
          'some work
          bgworker.reportprogress
       loop
    end sub
    end class
  • or this (which is what I meant in previous post):
    VB.NET:
    class form
    withevents DBobj as new DB
    
    sub DBobj_progress() handles DBobj.progress
       me.progressbar.value = e.progresspercent
    end sub
    
    sub dowork()
       DBobj.doworkasync
    end sub
    
    end class
    VB.NET:
    class DB
    
    public event progress As ProgressChangedEventHandler
    
    public sub doworkasync
      bgworker.runworkerasync
    end sub
    
    private withevents bgworker
    
    private sub bgworker_progress() handles bgworker.progress
       raiseevent progress(Me, e)
    end sub
    
    private sub bgworker_dowork() handles bgworker.dowork
       do
          'some work
          bgworker.reportprogress
       loop
    end sub
    
    end class
You see with the last option the DB class is completely standalone and has no dependencies with a bgworker instance in form. It does work async and raises event, which any consumer of that object may choose to subscribe to.
 
Back
Top