Access progress bar on main form from thread on user control

Grega

Active member
Joined
Jun 21, 2007
Messages
25
Programming Experience
1-3
Hi,

I ran into a problem that I just cannot figure out.

I have a windows application with a main form, on which a user control is added dynamically when a device connects trough USB.

On a user control, there is a thread wich is getting data from the device trough USB and when it is finished, I want to change a progressbar that is located on the main windows form where user control reside.

This is the code that is I call on the user control thread to change the progress bar value:
VB.NET:
Frm_Main.UpdateProgressBar(CInt((AllBytesReceived / MaxBytesInFlash) * 100))

and this is a code that is called on the main form:

VB.NET:
   Private Delegate Sub UpdateProgressBarDelegate(ByVal value As Integer)

    Dim _UpdateProgressBarDelegate As New UpdateProgressBarDelegate(AddressOf UpdateProgressBar)

 Public Sub UpdateProgressBar(ByVal value As Integer)
        If Me.ProgressBar1.InvokeRequired Then
            Invoke(_UpdateProgressBarDelegate, value)
        Else
            If value <= 100 Then
                If Me.ProgressBar1.Value <> value Then
                        Me.ProgressBar1.Value = value
                        If value = 100 Then
                        Me.BtnDownloadData.Text = "Download Data"
                    End If
                End If
            End If
        End If
    End Sub

but the progress bar does not change!

Any help would be greatly appreciated!

Thanks
Greg
 
Thanks John for your reply,

sorry I am a pain but I don't quite know how to use this "FrmMain.Invoke(New Del(AddressOf me.show)) " in my code....

Regards,
Greg
 
Nevermind the quoted code from oXiDe, read the reply I wrote, it is equally relevant for you.
 
Hey John,

sorry I missunderstood your post I thought I need to use the code.

Anyway I still have no idea how to do this.

Should I make a reference on my user control and pass it to the UpdateProgressBar sub on the main form?


Thank you for helping.

regards,
Greg
 
Grega said:
Frm_Main.UpdateProgressBar
Are you, or are you not, referencing default form instance of Frm_Main here ?
If you are, which it seems to be, then I have explained that you can't do that from a secondary thread.
There are two solutions to this;
  1. pass the form instance from UI thread (Me) to the class performing the thread work. Use this instance to call the UpdateProgress.
  2. or, instead of the worker thread saying what to do in UI, you can write an event and raise it to notify that progress has changed, the UI can listen for this event and report the progress to user. This is the better solution of these two IMO.
The alternative solution is as mentioned to use the BackgroundWorker component, it is easy to work with across worker thread and UI thread.
 
Thanks for this,

as soon as I read the first point I remembered that I had already done this once in some other project. This did the trick immediately.

Can I just ask you why do you think the second option is better?
I know how to do the second to.

Thanks again!

Regards,
Greg
 
Can I just ask you why do you think the second option is better?
Because it is better object oriented programming. Let's say you have two classes, form UI and worker W. UI here creates one or more W objects to do work tasks. The W class doesn't need to know anything about the UI class, it only needs to perform the work and report the progress. If you design W to call the UI instance you are creating a dependency in W class, a close link that doesn't need to be there. By defining an event in W class each W instance can report the progress independently of other classes and instances, the UI can listen to this event if it cares to know. Without this dependency also other classes can create W instances to do work and listen to the event, so the W class can be reused without modification.
 
Back
Top