Home All Groups Group Topic Archive Search About

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

Author
25 May 2010 6:08 PM
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

Author
25 May 2010 6:17 PM
Tom Shelton
Roidy formulated on Tuesday :
Show quoteHide quote
> 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

--
Tom Shelton
Author
25 May 2010 6:36 PM
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

Show quoteHide quote
>
> Dim pBox As New Progressbox ("Test caption", AddressOf workSub)
>
> HTH
>
> --
> Tom Shelton
>
>
Author
25 May 2010 6:44 PM
Tom Shelton
Roidy formulated on Tuesday :
Show quoteHide quote
> 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
>
>>
>> Dim pBox As New Progressbox ("Test caption", AddressOf workSub)
>>
>> HTH
>>
>> -- Tom Shelton
>>
>>

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

--
Tom Shelton
Author
25 May 2010 7:28 PM
Roidy
Thanks Tom that did it. Works perfectly.

Robert


Show quoteHide quote
"Tom Shelton" <tom_shelton@comcast.invalid> wrote in message
news:hth5r3$jo3$1@news.eternal-september.org...

>
> 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
>
> --
> Tom Shelton
>
>
Author
26 May 2010 3:18 AM
Branco Medeiros
Roidy wrote:
> OK bear with me while I try to explain :)

Okie dokie =))

Show quoteHide quote
> 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.
Author
26 May 2010 9:24 AM
Roidy
Thanks, but for what I need it's easy just to keep the background worker in
the class.

Robert

Show quoteHide quote
"Branco Medeiros" <branco.medei***@gmail.com> wrote in message
news:df552d03-416d-49fe-b0b3-a8919fc958c0@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.