Umm.... How to pass a sub into a class......

R

Roidy

OK bear with me while I try to explain :)

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

Robert
 
T

Tom Shelton

Roidy formulated on Tuesday :
OK bear with me while I try to explain :)

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)
Dim pBox As New Progressbox ("Test caption", AddressOf workSub)

HTH
 
R

Roidy

Thanks Tom, but how do I then get the sub in the class and add it as a
handler? What type will it be?

Public Class ProgressBox
Public Sub New(ByVal txt as String, ???????????????<- How to get it)
InitProgBox()

AddHandler backgroundWorker1.DoWork, ??????????????????????

Me.Label1.text = txt
Me.backgroundworker1.runWorkerAsync()
End Sub
End Sub
End Class

Thanks
rob
 
T

Tom Shelton

Roidy formulated on Tuesday :
Thanks Tom, but how do I then get the sub in the class and add it as a
handler? What type will it be?

Public Class ProgressBox
Public Sub New(ByVal txt as String, ???????????????<- How to get it)
InitProgBox()

AddHandler backgroundWorker1.DoWork, ??????????????????????

Me.Label1.text = txt
Me.backgroundworker1.runWorkerAsync()
End Sub
End Sub
End Class

Thanks
rob

In the class that is creating going to acutally host the event...


Private Sub DoWork (ByVal sender As Object, ByVal e As DoWorkEventArgs)
' do cool stuff
End Sub


''' declaring an instance in the class with the sub
Dim pBox As New ProgressBox("Test Caption", AddressOf DoWork)

'' in the progressBox Class Constructor
Public Sub New(ByVal caption As String, ByVal workSub As DoWorkEventHandler)
' do init
' add the handler
AddHandler _backgroundWorker.DoWork, workSub
End Sub

HTH
 
B

Branco Medeiros

Roidy said:
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.
 
R

Roidy

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

Robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top