Corey has already blogged on this, but here is my take.
Delegates are a tool to raise an event from one class to another, from one form to another, or any combination.
Lets say that you have a form that shows customers, and a popup dialog that gives you a grid of customers to choose from. We'd like to raise an event in the frmChooseCustomer to let frmCustomerEdit know that a customer has been chosen. So, lets start in frmChooseCustomer:
There are four tasks:
'declare a delegate
Public Delegate Sub gridRowDoubleClicked(ByVal strCustomerNumber As String)
'create a local instance of the delegate
Private RowDoubleClicked As gridRowDoubleClicked
'create a sub that the calling form can attach to
Public Sub NotifyRowDoubleClicked(ByVal value As gridRowDoubleClicked)
RowDoubleClicked = value
End Sub
'In the grid doubleclicked event (or however the customer number is selected), do this:
Private Sub Doubleclicked...
RowDoubleClicked.Invoke(strCustomerNumber)
End Sub
So, we're juggling three objects here - the delegate, the local instance of the delegate, and the sub that is attached to.
In the calling form (frmCustomerEdit), we do this:
Private Sub btnCustomerLookup_Click....
'create an instance of the 'choose customer' form
Dim frm As New SOPChooseCustomer
'attach to the notify sub
frm.NotifyRowDoubleClicked(New SOPChooseCustomer.gridRowDoubleClicked(AddressOf customerChosen))
'open the form modally
frm.ShowDialog()
End Sub
'notice that the signature is the same as the DELEGATE
Public Sub customerChosen(ByVal strCustomerNumber As String)
'this fires when the 'choose customer' fires the 'doubleClicked' event
Me.txtCustomerNumber.Text = strCustomerNumber
End Sub
In my case, the delegate has one string parameter. It can have zero or as many params as you want, of any type.
As always, comments are welcome