I will be showing how to pass data between two forms in VB .NET. I will be using two forms, two classes which we will define, a delegate, an event, and an event handler. It is my first tutorial and is a bit long because I wanted to make it easy to follow. If you want to skip the explanation and just see the code, scroll down to "The short version:"

Here is what I will be using:

  • A form named: MainFrm
  • A form named: ChildFrm
  • A class named: ScheduleInfo
  • A class named: ValueUpdatedEventsArgs

An instance of ChildFrm will be created and shown when clicking a button on the main form (MainFrm). After adding our data in the child form (ChildFrm), we will click a button on the child form to send the data back to the main form. Then on the main form we will display the newly received data, as well as add our data to a list (or update the data in the list if it was previously added).

Let's start out by creating "ScheduleInfo.vb". An instance of this class will be used to hold the data that we want to pass between the forms. It only contains two variables. You can add more if you like.

Public Class ScheduleInfo
    Public Name As String = String.Empty
    Public EventType As String = String.Empty
End Class

Next, we create "ValueUpdatedEventArgs.vb":

Public Class ValueUpdatedEventArgs

End Class

We want to inherit from System.EventArgs, so we add "Inherits System.EventArgs" like this:

Public Class ValueUpdatedEventArgs
    Inherits System.EventArgs

End Class

Next we want to use a delegate to help us transfer our data between forms. According to this documentation, a delegate "lets you dynamically associate event handlers with events by creating a delegate for you when you use the AddHandler statement. At run time, the delegate forwards calls to the appropriate event handler"

Let's add our delegate to "ValueUpdatedEventArgs.vb":

Public Delegate Sub ValueUpdatedEventHandler(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)

Public Class ValueUpdatedEventArgs
    Inherits System.EventArgs

End Class

Next, we want to have a place to store our data that we need to pass between forms. We will use an instance of "ScheduleInfo".

Public Delegate Sub ValueUpdatedEventHandler(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)

Public Class ValueUpdatedEventArgs
    Inherits System.EventArgs

    Private _schedule As ScheduleInfo

End Class

We need a way to get our data into our instance of "ValueUpdatedEventArgs", so let's create a constructor:

Public Delegate Sub ValueUpdatedEventHandler(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)

Public Class ValueUpdatedEventArgs
    Inherits System.EventArgs

    Private _schedule As ScheduleInfo

    'constructor
    Public Sub New(ByVal Schedule As ScheduleInfo)
        _schedule = Schedule
    End Sub

End Class

Now we need a way to get our data from "ValueUpdatedEventArgs". Let's use a "ReadOnly Property" called "Schedule":

Public Class ValueUpdatedEventArgs
    Inherits System.EventArgs

    Private _schedule As ScheduleInfo


    'constructor
    Public Sub New(ByVal Schedule As ScheduleInfo)
        _schedule = Schedule
    End Sub

    'returns Schedule data stored in _schedule
    Public ReadOnly Property Schedule As ScheduleInfo
        Get
            Return _schedule
        End Get
    End Property 'Schedule

End Class

We're finished with ValueUpdatedEventArgs. Next, let's look at the child form (ChildFrm).

Create a new "Windows Form" and name it "ChildFrm.vb".

Add a TextBox (named: nameTextBox), a ComboBox (named: eventTypeComboBox), and a button (named: addBtn) to the form (ChildFrm). Double-click the button to create a "Click" event handler for the button.

The code for ChildFrm should look like this:

Public Class ChildFrm1

    Private Sub addBtn_Click(sender As System.Object, e As System.EventArgs) Handles addBtn.Click

    End Sub

End Class

We want to create an event (in ChildFrm) that can be raised in ChildFrm that the main form (MainFrm) can listen for (and handle). We do it like this:

'Event interested parties can register with to know
'when value is updated.
'ValueUpdatedEventHandler is delegate defined in ValueUpdatedEventArgs

Public Event ValueUpdated As ValueUpdatedEventHandler

Our code will now look like this:

Public Class ChildFrm1

    'Event interested parties can register with to know
    'when value is updated.
    'ValueUpdatedEventHandler is delegate defined in ValueUpdatedEventArgs

    Public Event ValueUpdated As ValueUpdatedEventHandler


    Private Sub addBtn_Click(sender As System.Object, e As System.EventArgs) Handles addBtn.Click

    End Sub

End Class

Let's create an instance of ScheduleInfo to hold our data that we want to pass back to the main form (MainFrm).

'create new instance of ScheduleInfo
 Private myScheduleInfo As New ScheduleInfo

Now, let's create a Sub that we can use to send our data back to the main form (MainFrm).

    Private Sub SendUpdates(ByVal schedule As ScheduleInfo)


    End Sub

Here's what we want to do inside "SendUpdates". We want to declare a new instance of "ValueUpdatedEventArgs" and pass our local copy of ScheduleInfo to the constructor.

'create a new instance of ValueUpdatedEventArgs
Dim valueArgs As ValueUpdatedEventArgs
valueArgs = New ValueUpdatedEventArgs(schedule)

So now we have:

Private Sub SendUpdates(ByVal schedule As ScheduleInfo)

    'create a new instance of ValueUpdatedEventArgs
    Dim valueArgs As ValueUpdatedEventArgs
    valueArgs = New ValueUpdatedEventArgs(schedule)

End Sub

Next, we raise the event:

'raise event "ValueUpdated"
'Me refers to this class
'valueArgs is a new instance of "ValueUpdatedEventArgs"
'and contains our schedule information
'we want to pass to the main form (mainFrm)

RaiseEvent ValueUpdated(Me, valueArgs)

Here's what "SendUpdates" will look like when finished.

    Private Sub SendUpdates(ByVal schedule As ScheduleInfo)

        'The following lines will raise an event.
        'In essence, will send the data to the main form
        'because the main form (mainFrm) has subscribed to
        'events on this form and is listening for them.
        '
        'The data type(s) need to be the same data type(s)
        'that is/are defined in "ValueUpdatedEventArgs".
        '
        'If numerous variables are to be passed, it is
        'recommended to use a "public class" for them

        'create a new instance of ValueUpdatedEventArgs
        Dim valueArgs As ValueUpdatedEventArgs
        valueArgs = New ValueUpdatedEventArgs(schedule)

        'raise event "ValueUpdated"
        'Me refers to this class
        'valueArgs is a new instance of "ValueUpdatedEventArgs"
        'and contains our schedule information
        'we want to pass to the main form (mainFrm)

        RaiseEvent ValueUpdated(Me, valueArgs)

    End Sub

We're almost done. Right-click "Form1.vb" and select "Rename". Rename it to "MainFrm.vb".
Add two textboxes on MainFrm (named: TextBox1 and TextBox2) and a button (named: openChildFrm1Btn).
Double-click the button to create a "Click" event handler for the button.

The code for MainFrm should look like this:

Public Class MainFrm


    Private Sub openChildFrm1Btn_Click(sender As System.Object, e As System.EventArgs) Handles openChildFrm1Btn.Click

    End Sub

End Class

Create a new instance of ScheduleInfo:

'create new instance of ScheduleInfo
Private mySchedule As New ScheduleInfo

Create a new List of type ScheduleInfo:

'create new List of type ScheduleInfo
Private myScheduleList As New List(Of ScheduleInfo)

Create an instance of ChildFrm:

'create instance of childFrm1
Private myChildFrm1 As childFrm1

Now, the code should look like this:

Public Class MainFrm

    'create new instance of ScheduleInfo
    Private mySchedule As New ScheduleInfo

    'create new List of type ScheduleInfo
    Private myScheduleList As New List(Of ScheduleInfo)

    'create instance of childFrm1
    Private myChildFrm1 As childFrm1

    Private Sub openChildFrm1Btn_Click(sender As System.Object, e As System.EventArgs) Handles openChildFrm1Btn.Click

    End Sub

End Class

Next, we will create the event handler. This will be called every time the "ValueUpdated" event is raised in our ChildFrm.

We follow the same form as our delegate that is defined in "ValueUpdatedEventArgs.vb". "myChildFrm1_ValueUpdated" is what I chose to name the event handler--the name can be anything, but should be descriptive so we know what it is.

'event handler
'this is called every time myChildFrm1.ValueUpdated event occurs
Private Sub myChildFrm1_ValueUpdated(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)


End Sub

An instance of ScheduleInfo is passed to "myChildFrm1_ValueUpdated" in parameter "e". We use Property "Schedule" to access the data. So we would access Name, like this:

e.Schedule.Name

We want to create a new instance of ScheduleInfo every time the event handler is called and either add the data to our list or update the existing data if the entry already exists. Additionally, we will update TextBox1 and TextBox2 with the data we just received.

    'event handler
    'this is called every time myChildFrm1.ValueUpdated event occurs
    Private Sub myChildFrm1_ValueUpdated(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)

        'used to determine if we need to update our list
        'or add mySchedule to the list
        Dim scheduleExists As Boolean = False

        ' update TextBox1, setting the value 
        ' to the value from myChildFrm1
        ' "e" contains an instance of
        ' ScheduleInfo that contains
        ' our data from childFrm1.
        ' We get our data from Property 'Schedule'
        ' which is an instance of 'ScheduleInfo'

        'create new instance of ScheduleInfo
        mySchedule = New ScheduleInfo()

        'get "Name" from instance of ScheduleInfo
        'returned by our event and store in
        'our local instance of ScheduleInfo
        mySchedule.Name = e.Schedule.Name


        'get "EventType" from instance of ScheduleInfo
        'returned by our event and store in
        'our local instance of ScheduleInfo
        mySchedule.EventType = e.Schedule.EventType

        'check list to see if entry already exists
        For i As Integer = 0 To myScheduleList.Count - 1

            'if "name" passed back from child form exists
            'in our list, update the list with the new information
            If String.Compare(myScheduleList(i).Name, mySchedule.Name) = 0 Then
                'update myScheduleList with info
                'in mySchedule

                myScheduleList(i) = mySchedule

                'set scheduleExists = True so
                'we know not to add mySchedule to the list
                scheduleExists = True

                Exit For 'exit loop
            End If
        Next

        'if name was not found, add mySchedule
        'to myScheduleList
        If scheduleExists = False Then
            'add mySchedule to myScheduleList
            myScheduleList.Add(mySchedule)
        End If

        'set text in TextBox1 to Name
        TextBox1.Text = mySchedule.Name

        'set text in TextBox2 to EventType
        TextBox2.Text = mySchedule.EventType

        'print out our list. This is for demonstration purposes.
        'You might update a file here, instead or choose
        'to do nothing else.

        Console.WriteLine("")
        For Each sched As ScheduleInfo In myScheduleList
            Console.WriteLine("Name: " & sched.Name & " Event Type: " & sched.EventType)
        Next

    End Sub

Lastly, we need to add code for when the "openChildFrm1Btn" button is clicked. We want to create a new instance of the form (ChildFrm), add a handler to handle the "ValueUpdated" event in ChildFrm, and then show the form.

    Private Sub openChildFrm1Btn_Click(sender As System.Object, e As System.EventArgs) Handles openChildFrm1Btn.Click

        'create new instance of childFrm1
        myChildFrm1 = New ChildFrm1()

        'add listener / event handler for myChildFrm1.ValueUpdated event
        AddHandler myChildFrm1.ValueUpdated, AddressOf myChildFrm1_ValueUpdated

        'show the form
        myChildFrm1.Show()
    End Sub

Here's the final version of "MainFrm.vb":

Public Class MainFrm

    'create new instance of ScheduleInfo
    Private mySchedule As New ScheduleInfo

    'create new List of type ScheduleInfo
    Private myScheduleList As New List(Of ScheduleInfo)

    'create instance of childFrm1
    Private myChildFrm1 As childFrm1

    Private Sub openChildFrm1Btn_Click(sender As System.Object, e As System.EventArgs) Handles openChildFrm1Btn.Click

        'create new instance of childFrm1
        myChildFrm1 = New ChildFrm1()

        'add listener / event handler for myChildFrm1.ValueUpdated event
        AddHandler myChildFrm1.ValueUpdated, AddressOf myChildFrm1_ValueUpdated

        'show the form
        myChildFrm1.Show()
    End Sub

    'event handler
    'this is called every time myChildFrm1.ValueUpdated event occurs
    Private Sub myChildFrm1_ValueUpdated(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)

        'used to determine if we need to update our list
        'or add mySchedule to the list
        Dim scheduleExists As Boolean = False

        ' update TextBox1, setting the value 
        ' to the value from myChildFrm1
        ' "e" contains an instance of
        ' ScheduleInfo that contains
        ' our data from childFrm1.
        ' We get our data from Property 'Schedule'
        ' which is an instance of 'ScheduleInfo'

        'create new instance of ScheduleInfo
        mySchedule = New ScheduleInfo()

        'get "Name" from instance of ScheduleInfo
        'returned by our event and store in
        'our local instance of ScheduleInfo
        mySchedule.Name = e.Schedule.Name


        'get "EventType" from instance of ScheduleInfo
        'returned by our event and store in
        'our local instance of ScheduleInfo
        mySchedule.EventType = e.Schedule.EventType

        'check list to see if entry already exists
        For i As Integer = 0 To myScheduleList.Count - 1

            'if "name" passed back from child form exists
            'in our list, update the list with the new information
            If String.Compare(myScheduleList(i).Name, mySchedule.Name) = 0 Then
                'update myScheduleList with info
                'in mySchedule

                myScheduleList(i) = mySchedule

                'set scheduleExists = True so
                'we know not to add mySchedule to the list
                scheduleExists = True

                Exit For 'exit loop
            End If
        Next

        'if name was not found, add mySchedule
        'to myScheduleList
        If scheduleExists = False Then
            'add mySchedule to myScheduleList
            myScheduleList.Add(mySchedule)
        End If

        'set text in TextBox1 to Name
        TextBox1.Text = mySchedule.Name

        'set text in TextBox2 to EventType
        TextBox2.Text = mySchedule.EventType

        'print out our list. This is for demonstration purposes.
        'You might update a file here, instead or choose
        'to do nothing else.

        Console.WriteLine("")
        For Each sched As ScheduleInfo In myScheduleList
            Console.WriteLine("Name: " & sched.Name & " Event Type: " & sched.EventType)
        Next

    End Sub
End Class

The short version:

  1. Create a new project (select "Windows Forms Application")
  2. Right-click "Form1.vb" in Solution Explorer and choose "Rename". Rename it to "MainFrm.vb". You should be prompted, "You are renaming a file. Would you like to perform a rename in this project of all references....?" Click, "Yes".
  3. Add two textboxes (named: TextBox1 and TextBox2) and one button (named: openChildFrm1Btn) to MainFrm.
  4. Double-click the button. It will create "Private Sub openChildFrmBtn_Click"
  5. Replace the code in MainFrm with the following code:

    'MainFrm.vb
    '
    'Subject: form communication
    '
    'Description:
    'This example shows how to send data from one form (childFrm)
    'to another form (mainFrm). It uses a user-defined class, a delegate, 
    'an event, and an event handler.
    '
    'Notes:
    'This example requires two textboxes on mainFrm (named: TextBox1 and TextBox2)
    'and one button (named: openChildFrm1Btn).
    'It also requires "ChildFrm.vb" and "ValueUpdatedEventArgs.vb", and
    'ScheduleInfo.vb
    '
    'Written: 03/10/2014 by cg
    
    Public Class MainFrm
    
        'create new instance of ScheduleInfo
        Private mySchedule As New ScheduleInfo
    
        'create new List of type ScheduleInfo
        Private myScheduleList As New List(Of ScheduleInfo)
    
        'create instance of childFrm1
        Private myChildFrm1 As childFrm1
    
        Private Sub openChildFrm1Btn_Click(sender As System.Object, e As System.EventArgs) Handles openChildFrm1Btn.Click
    
            'create new instance of childFrm1
            myChildFrm1 = New ChildFrm1()
    
            'add listener / event handler for myChildFrm1.ValueUpdated event
            AddHandler myChildFrm1.ValueUpdated, AddressOf myChildFrm1_ValueUpdated
    
            'show the form
            myChildFrm1.Show()
        End Sub
    
        'event handler
        'this is called every time myChildFrm1.ValueUpdated event occurs
        Private Sub myChildFrm1_ValueUpdated(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)
    
            'used to determine if we need to update our list
            'or add mySchedule to the list
            Dim scheduleExists As Boolean = False
    
            ' update TextBox1, setting the value 
            ' to the value from myChildFrm1
            ' "e" contains an instance of
            ' ScheduleInfo that contains
            ' our data from childFrm1.
            ' We get our data from Property 'Schedule'
            ' which is an instance of 'ScheduleInfo'
    
            'create new instance of ScheduleInfo
            mySchedule = New ScheduleInfo()
    
            'get "Name" from instance of ScheduleInfo
            'returned by our event and store in
            'our local instance of ScheduleInfo
            mySchedule.Name = e.Schedule.Name
    
    
            'get "EventType" from instance of ScheduleInfo
            'returned by our event and store in
            'our local instance of ScheduleInfo
            mySchedule.EventType = e.Schedule.EventType
    
            'check list to see if entry already exists
            For i As Integer = 0 To myScheduleList.Count - 1
    
                'if "name" passed back from child form exists
                'in our list, update the list with the new information
                If String.Compare(myScheduleList(i).Name, mySchedule.Name) = 0 Then
                    'update myScheduleList with info
                    'in mySchedule
    
                    myScheduleList(i) = mySchedule
    
                    'set scheduleExists = True so
                    'we know not to add mySchedule to the list
                    scheduleExists = True
    
                    Exit For 'exit loop
                End If
            Next
    
            'if name was not found, add mySchedule
            'to myScheduleList
            If scheduleExists = False Then
                'add mySchedule to myScheduleList
                myScheduleList.Add(mySchedule)
            End If
    
            'set text in TextBox1 to Name
            TextBox1.Text = mySchedule.Name
    
            'set text in TextBox2 to EventType
            TextBox2.Text = mySchedule.EventType
    
            'print out our list. This is for demonstration purposes.
            'You might update a file here, instead or choose
            'to do nothing else.
    
            Console.WriteLine("")
            For Each sched As ScheduleInfo In myScheduleList
                Console.WriteLine("Name: " & sched.Name & " Event Type: " & sched.EventType)
            Next
    
        End Sub
    End Class
    

Create "ScheduleInfo.vb"

  1. In menu bar, click "Project"
  2. Select "Add New Item"
  3. Select "Class". In name, type: "ScheduleInfo.vb"
  4. Click "Add"
  5. Replace the code in "ScheduleInfo.vb" with the following code:

    'ScheduleInfo.vb
    '
    'Subject: form communication
    '
    'Description:
    'An instance of this class is used to pass data from one form to another. 
    
    Public Class ScheduleInfo
        Public Name As String = String.Empty
        Public EventType As String = String.Empty
    End Class
    

Create "ValueUpdatedEventArgs.vb"

  1. In menu bar, click "Project"
  2. Select "Add New Item"
  3. Select "Class". In name, type: "ValueUpdatedEventArgs.vb"
  4. Click "Add"
  5. Replace the code in "ValueUpdatedEventArgs.vb" with the following code:

    'ValueUpdatedEventArgs.vb
    '
    'Subject: form communication
    '
    'Description:
    'This class is used to pass data from one form to another. It inherits
    'from System.EventArgs.
    
    Public Delegate Sub ValueUpdatedEventHandler(ByVal sender As Object, ByVal e As ValueUpdatedEventArgs)
    
    Public Class ValueUpdatedEventArgs
        Inherits System.EventArgs
    
        Private _schedule As ScheduleInfo
    
    
        'constructor
        Public Sub New(ByVal Schedule As ScheduleInfo)
            _schedule = Schedule
        End Sub
    
        'returns Schedule data stored in _schedule
        Public ReadOnly Property Schedule As ScheduleInfo
            Get
                Return _schedule
            End Get
        End Property 'Schedule
    
    End Class
    

Create "ChildFrm.vb"

  1. In menu bar, click "Project"
  2. Select "Add New Item"
  3. Select "Windows Form". In name, type: "ChildFrm.vb"
  4. Click "Add"
  5. Add one TextBox (named: TextBox1), one ComboBox (named: eventTypeComboBox), and one button (named: addBtn) to ChildFrm.
  6. Replace the code in "ChildFrm.vb" with the following code:

    'ChildFrm1.vb
    '
    'Subject: form communication
    '
    'Description:
    'This is the child form. It uses an event to pass it's data back 
    'to the calling form (MainFrm).
    
    
    Public Class ChildFrm1
    
        'Event interested parties can register with to know
        'when value is updated.
        'ValueUpdatedEventHandler is delegate defined in ValueUpdatedEventArgs
    
        Public Event ValueUpdated As ValueUpdatedEventHandler
    
        'create new instance of ScheduleInfo
        Private myScheduleInfo As New ScheduleInfo
    
    
        Private Sub addBtn_Click(sender As System.Object, e As System.EventArgs) Handles addBtn.Click
    
            'get Name from nameTextBox
            myScheduleInfo.Name = nameTextBox.Text
    
            'get EventType from eventTypeComboBox
            myScheduleInfo.EventType = eventTypeComboBox.Text
    
            'send updates to mainFrm
            SendUpdates(myScheduleInfo)
        End Sub
    
        Private Sub SendUpdates(ByVal schedule As ScheduleInfo)
    
            'The following lines will raise an event.
            'In essence, will send the data to the main form
            'because the main form (mainFrm) has subscribed to
            'events on this form and is listening for them.
            '
            'The data type(s) need to be the same data type(s)
            'that is/are defined in "ValueUpdatedEventArgs".
            '
            'If numerous variables are to be passed, it is
            'recommended to use a "public class" for them
    
            'create a new instance of ValueUpdatedEventArgs
            Dim valueArgs As ValueUpdatedEventArgs
            valueArgs = New ValueUpdatedEventArgs(schedule)
    
            'raise event "ValueUpdated"
            'Me refers to this class
            'valueArgs is a new instance of "ValueUpdatedEventArgs"
            'and contains our schedule information
            'we want to pass to the main form (mainFrm)
    
            RaiseEvent ValueUpdated(Me, valueArgs)
    
        End Sub
    
    End Class
    

Edited 2 Years Ago by Dani: Typo in title

Comments
An often asked subject well done!
Nice tutorial.

Been learning about delegates and events online (in C# for a VB project) all night without sleep but trying to convert to VB while learning (new to both) is difficult.
An excellent tutorial exactly what need, I'll be glued to the screen for several more hours yet. Thanks so much.

oops duplicated my post where's the delete?

Edited 1 Year Ago by Tuvok: duplicate by mistake

Note that this same technique can be used between a dll and a FORM. Note that the dll will have to run on a separate thread, the same as the two forms in this example do.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.