Exposing User Control Events of the RepeatedControl

When you create a user control, it's common to create public events. When the user control is placed on a standard Visual Basic form, the custom events automatically appear in the form's code module.

With the DataRepeater control, however, exposing the user control's events is not an automatic occurrence. Because the user control is not put directly on a form, its events cannot be exposed in the code module. There is, however, a way of achieving the same end.

In brief, the major steps are:

  1. Add a class module to the user control project, and name the module CtlEvents.

  2. Add a public event to the module named ProductChange.

  3. Add a public procedure to the module named FireControlChange that raises the ProductChange event (using the RaiseEvent statement).

  4. Add a public property to the user control named Events that returns a reference to the CtlEvents object.

  5. In the Change event of each constituent control of the user control, invoke the FireControlChange procedure to raise events.

Note   The following step-by-step procedure builds on the user control and DataRepeater control project built in the topic "Using the DataRepeater Control."

Creating events to be exposed by the user control

  1. Add a Class Module to the ActiveX Control project.

  2. Change the name of the class module from Class1 to CtlEvents.

  3. Set the Instancing property to 6GlobalMultiuse.

  4. Add a public event declaration to the Declarations section of the class module. For demonstration purposes, the code below adds only one event declaration. In a real application, you would add one event declaration for every control on the user control.
    Option Explicit
    Public Event ProductChange()
    
  5. Add a public procedure to the class module. In the procedure, add the RaiseEvent statement to raise the ProductChange event. This procedure is invoked in events of the UserControl, and its sole purpose is to raise the event.
    Public Sub FireControlChange()
    RaiseEvent ProductChange
    End Sub
    

    The ProductChange event is the event that will be exposed by CtlEvents when using the ProductsCtl user control in a DataRepeater control.

  6. In the user control object's code module, declare a variable typed as the new class, as shown below:
    Option Explicit
    Dim EventsObj As New CtlEvents
    
  7. Add a public Get procedure to the user control. In the procedure, use a Set statement to return the object reference.
    Public Property Get Events() As CtlEvents
    Set Events = EventsObj ' returns the CtlEvents object reference
    End Property
    
  8. In the Change event of the control you want to monitor, invoke the class object's procedure:
    Private Sub txtProductName_Change()
    PropertyChanged ("ProductName")
    EventsObj.FireControlChange
    End Sub
    
  9. Save and compile the project (make the .ocx).

To expose the events of the User Control in the container form

The following steps take place in the project that contains the DataRepeater control. In that project, a DataRepeater control contains the user control with the events created in steps 1 to 9 above.

  1. In the project that contains the DataRepeater control, use the Components dialog box to add the ProductsCtl (ProductsCtl.ocx) to the Toolbox. This step is needed to ensure that the Visual Basic Package and Deployment Wizard will correctly include the necessary .ocx file with the project. It also allows access at design time to the ProductsCtl events in code.

  2. In the Declarations section of the Form object's code module, paste the following code that declares an object variable with the WithEvents keyword:
    Option Explicit
    Dim WithEvents objRepCtl As CtlEvents ' Be sure to use WithEvents
    
  3. In the DataRepeater control's RepeatedControlLoaded event set the variable to the Events property. You must set the variable using the DataRepeater control's RepeatedControl property, as shown below:
    Private Sub DataRepeater1_RepeatedControlLoaded()
    Set objRepCtl = DataRepeater1.RepeatedControl.Events
    End Sub

    Because you can set the RepeatedControlName property at run time, the RepeatedControlLoaded was designed to allow you to set control properties that can only be initialized after the control has been loaded.

  4. The new object objRepCtl (with events) should now appear in the drop-down list of the Object box, in the upper left corner of the code module. Select the object from the list, and add code to the event of the object, as shown below.
    Private Sub objRepCtl_ProductChange()
     Debug.Print "objRepCtl_ProductChange"
    End Sub
    
  5. Run the project. When you alter the Products field, the event will occur.

Adding Events to the Control

With a few simple additions of code, you can easily add more events to the user control. First add public events — one for each event you want to raise — to the class module:

Option Explicit
Public Event ProductChange()
Public Event UnitPriceChange() ' <- This is a new Event declaration.

Then add an argument to the class module's FireControlChange procedure. A Select Case statement is added to the procedure to distinguish which control is calling the procedure. Using that argument, the correct event is raised:

Public Sub FireControlChange(ctlName As String)
   Select Case ctlName
   Case "ProductName"
      RaiseEvent ProductChange
   Case "UnitPrice"
      RaiseEvent UnitPriceChange
   Case Else
      ' Handle other cases here.
   End Select
End Sub

Finally, switch to the UserControl object's code module. In the Change event of the controls you wish to monitor, invoke the procedure with the correct argument, as shown below.

Private Sub txtProductName_Change()
   PropertyChanged "ProductName"
   EventsObj.FireControlChange "ProductName" ' Invoke procedure.
End Sub

Private Sub txtUnitPrice_Change()
   PropertyChanged "UnitPrice"
   EventsObj.FireControlChange "UnitPrice" ' Invoke procedure.
End Sub