From: Branco Medeiros on
Roidy wrote:
> OK bear with me while I try to explain :)

Okie dokie =))

> I'm writing a program where I need to do a lot of different background
> worker tasks and display the progress in a dialog box. So rather than create
> a separate dialog for each task I created a class that displays a dialog and
> fires off a background worker, what I can't seem to do is pass a dowork
> handler sub into the class.  This is basically what I've got so far:-
>
> MainForm code:-
>
> .......
>     Dim pBox as New ProgressBox("Test caption")
>     pBox.ShowDialog()
>
> Sub worksub()
>     .........
>     Do background work here
>     .........
> End Sub
> .......
>
> Class code:-
>
> Public Class ProgressBox
>     Public Sub New(ByVal txt as String)
>         InitProgBox()
>         Me.Label1.text = txt
>         Me.backgroundworker1.runWorkerAsync()
>     End Sub
>
>     Public Sub InitProgBox()
>         ..........
>         ..........
>         Code to set up the dialog and background worker
>         ..........
>         ..........
>     End Sub
> End Class
>
> I can happily pass string and other variables in to the class but when I
> create a new instance of ProgressBox I need to be able to pass worksub into
> it and have it added as the handler of the backgroundworkers DoWork
> function. I just can't figure out how to pass worksub into the class along
> the lines of:-
>
> Dim pBox as New ProgressBox("Test caption", worksub)
>
> Help please

Instead of hosting the background worker in the dialog class, I
usually prefer to have it in the main form. This way the progress form
cna be more generic, and I can reuse it even when there's no
background worker involved

When the progress dialog is shown (modally), it raises an event that
is handled by the parent form. At this point the parent form regains
control (even though there's a modal form on the screen) and can
launch the background worker (or whatever form of multithreading) to
perform the desired action.

It also can handle the progress event of the background worker and
feed the progress dialog with relevant information about the progress
of the operation.

Something like this:

.... In the main form:

Private WithEvents ProgressDlg As ProgressForm
...
...
...
Using Dlg as New ProgressForm
ProgressDlg = Dlg
Dlg.Action = CInt(Actions.TheAction)
Dlg.ShowDialog(Me)
End Using
...
...
...
Private Sub ProgressDlg_StartAction( _
Sender As Object, _
e As ProgressEventArgs _
) Handles ProgressDlg.StartAction

'passes the action code to a local bg worker,
'which will decide on what action to execute

'Instead of a bg worker, I could use a thread pool
'or launch a separate process, whatever

CTLBgWorker.RunWorkerAsync(e.Action)
End Sub


Private Sub CTLBgWorker_ProgressChanged(...) _
Handles CTLBgWorker.ProgressChanged
'when there's a change in the bg worker progress,
'report back to the progress dialog
ProgressDlg.Progress = e.ProgressPercentage
End Sub

As for the progress dialog, it's something in the lines of

Class ProgressForm
Inherits Form

Public Event StartAction(...)
'you can also handle these other (very usefull) events
Public Event PauseAction(...)
Public Event CancelAction(...)

Public Property Action As Integer
...
End Property

Private Sub Form_Shown(...) _
Handles me.Shown
OnStartAction(...)
End Sub

Protected Sub OnStartAction(...)
RaiseEvent StartAction(Me, e)
End Sub

etc, etc. I guess you got the idea. Hope it helps.

Best regards,

Branco.
From: Roidy on
Thanks, but for what I need it's easy just to keep the background worker in
the class.

Robert

"Branco Medeiros" <branco.medeiros(a)gmail.com> wrote in message
news:df552d03-416d-49fe-b0b3-a8919fc958c0(a)y21g2000vba.googlegroups.com...

> Instead of hosting the background worker in the dialog class, I
> usually prefer to have it in the main form. This way the progress form
> cna be more generic, and I can reuse it even when there's no
> background worker involved
>
> When the progress dialog is shown (modally), it raises an event that
> is handled by the parent form. At this point the parent form regains
> control (even though there's a modal form on the screen) and can
> launch the background worker (or whatever form of multithreading) to
> perform the desired action.
>
> It also can handle the progress event of the background worker and
> feed the progress dialog with relevant information about the progress
> of the operation.
>
> Something like this:
>
> .... In the main form:
>
> Private WithEvents ProgressDlg As ProgressForm
> ...
> ...
> ...
> Using Dlg as New ProgressForm
> ProgressDlg = Dlg
> Dlg.Action = CInt(Actions.TheAction)
> Dlg.ShowDialog(Me)
> End Using
> ...
> ...
> ...
> Private Sub ProgressDlg_StartAction( _
> Sender As Object, _
> e As ProgressEventArgs _
> ) Handles ProgressDlg.StartAction
>
> 'passes the action code to a local bg worker,
> 'which will decide on what action to execute
>
> 'Instead of a bg worker, I could use a thread pool
> 'or launch a separate process, whatever
>
> CTLBgWorker.RunWorkerAsync(e.Action)
> End Sub
>
>
> Private Sub CTLBgWorker_ProgressChanged(...) _
> Handles CTLBgWorker.ProgressChanged
> 'when there's a change in the bg worker progress,
> 'report back to the progress dialog
> ProgressDlg.Progress = e.ProgressPercentage
> End Sub
>
> As for the progress dialog, it's something in the lines of
>
> Class ProgressForm
> Inherits Form
>
> Public Event StartAction(...)
> 'you can also handle these other (very usefull) events
> Public Event PauseAction(...)
> Public Event CancelAction(...)
>
> Public Property Action As Integer
> ...
> End Property
>
> Private Sub Form_Shown(...) _
> Handles me.Shown
> OnStartAction(...)
> End Sub
>
> Protected Sub OnStartAction(...)
> RaiseEvent StartAction(Me, e)
> End Sub
>
> etc, etc. I guess you got the idea. Hope it helps.
>
> Best regards,
>
> Branco.