I have several classes that can raise same event: classA, classB, classC all can RaiseEvent "DlFinished", "TableUpdated", "ReportProgress". Since all 3 classes give me about the same information, I created an user control which displays the data. Now this may not be the best way to handle this situation, but I am just starting to learn programming in VB.Net, i handle it like this:

Public Class myUserControl
    Private WithEvents _d As Object
    Public Sub New(ByRef d As classA)
        _d = d
        InitializeComponent()
    End Sub
    Public Sub New(ByRef d As classB)
        _d = d
        InitializeComponent()
    End Sub
    Public Sub New(ByRef d As classC)
        _d = d
        InitializeComponent()
    End Sub
    ...
End Class

The controls seems to work fine, but they cannot get the events fired by the classes. If I try to handle the events within "myUserControl" with something like :

    Private Sub _d_ReportProgress(percentage As Integer, message As String) Handles _d.ReportProgress
        'misc code here ...
    End Sub

i get the following error:

Error 74 Event 'ReportProgress' cannot be found.

I would appreciate any suggestion. I also considered creating a class that has these events (classMain) then having my classA, classB, classC inheriting classMain, but I am not sure that would work either.

Thank you for your help

Recommended Answers

All 2 Replies

Can you show the code where ReportProgress event is fired?
Is your it being called by your classes?
Are your Classes in the form/module/Class that the sub is in?
You have declared the sub to be Private that means it can only be called by Routines in the same module/class/form as it. You will need to either use Public Sub or Friend Sub if they are not...

I may have not explained the problem very well the first time.

This is an example of MyClassA. MyClassB, MyClassC are doing pretty much the same thing as they all read stock data from various distributors and generate access tables.

Imports *imports needed for class*
Public Class MyClassA
    ... other variables
    ... other events
    Public Event DownloadFinished()
    Public Event ReportProgress(ByVal percentage As Integer, ByVal message As String)

    Shared myInstance As MyClassA
    Public Shared Function GetInstance() As MyClassA
        If myInstance Is Nothing Then
            myInstance = New MyClassA()
        End If
        Return myInstance
    End Function

    Public Sub New()
        ...load settings and initialize variables
    End Sub

    Public Sub DownloadData()
        _processingDownload = True
        StartDownload()
        ExtractAll()
    End Sub 

    Private _processingDownload As Boolean = False
    Private Sub StartDownload()
        Dim URI, localFile As String
        RaiseEvent ReportProgress(0, "Connecting to FTP Server...")
        URI = _ftpHost & _ftpPriceFolder & "/" & _File
        localFile = _saveFolder & "\" & _File
        DownloadFile(URI, localFile)
    End Sub

    Private Sub ExtractAll()
        Dim priceFile As String = _saveFolder & "\" & _File
        RaiseEvent ReportProgress(0, "Decompressing Data...")
        ... run zip extraction code
        RaiseEvent ReportProgress(100, "Data Transfer Complete...")
        RaiseEvent DownloadFinished()
    End Sub
End Class

My control is supposed to show values for items in stock / out of stock / new items / errors for the distributors:

ucDistrib

If in the above control I click on "Update Now", the sub executes :

    ProgressGroup.Invoke(Sub() ProgressGroup.Visible = True)
    BusyPictureBox.Invoke(Sub() BusyPictureBox.Visible = True)
    Dim _DownloadData = New MethodInvoker(AddressOf _distributor.DownloadData)
    _DownloadData.BeginInvoke(Nothing, Nothing)

The Code runs great. Data is downloaded and then the table is generated. The only problem is I cannot read when Events have been fired. My problem is most likely in the way I have created my user control, and that's where I could use some help.

Public Class ucDistributorDataControl
    Private WithEvents _distributor As Object

    Public Sub New(ByRef distributor As MyClassA)
        _distributor = distributor
        InitializeComponent()
        RefreshCounterValues()
    End Sub
    Public Sub New(ByRef distributor As MyClassB)
        _distributor = distributor
        InitializeComponent()
        RefreshCounterValues()
    End Sub
    Public Sub New(ByRef distributor As MyClassC)
        _distributor = distributor
        InitializeComponent()
        RefreshCounterValues()
    End Sub

    Private Sub UpdateSplitButton_Click(sender As Object, e As EventArgs) Handles UpdateSplitButton.Click
        DownloadAndUpdateData()
    End Sub

    Private Sub _distributor_DownloadFinished() Handles _distributor.DownloadFinished
        ...update counters, progress bar and texts
    End Sub
    Private Sub _distributor_ReportProgress(percentage As Integer, message As String) Handles _distributor.ReportProgress
        ... update progress bar and texts
    End Sub
End Class

Since I am trying to send by reference the class that the user control will use to get it's data, I create it with

Dim _distrib As ucDistributorDataControl = New ucDistributorDataControl(MyClassA.GetInstance)
DistributorsFlowPanel.Controls.Add(_distrib)

and then eventually add it to my form

formDistrib

The problem is that

... Handles _distributor.DownloadFinished
and
... Handles _distributor.ReportProgress

are not recognized by my user control as valid events and then I have no way of knowing when those events occured in order to update my control.

I probably need a better way of defining _distributor inside the user control, but I do not know how to do that.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.