Creating a Data Source

In this section, we’ll walk step-by-step through the process of creating a data-aware class that acts as a data source. This example will bind a TextBox control to our data source class in order to display the data. The next section, "Creating a Data Consumer," demonstrates how to bind our data source class to a data consumer class.

The code examples in this section are taken from the Data-aware Classes (Dataware.vbp) sample. You'll find this application in the Samples directory.

Creating a data source is a two-step process. In the first step we’ll create the data source class; in the second step we’ll hook it up to a TextBox control in order to display the output.

Creating the Source Class

The first step in creating a source class is to define a new class and give it the properties and methods necessary to provide data:

  1. Open a new Standard EXE project, and insert a class module by selecting Add Class Module from the Project menu.

  2. In the Properties window, set the properties of the class as follows:
    Property Setting
    Name MySource
    DataSourceBehavior vbDataSource

    When DataSourceBehavior is set to vbDataSource, a new Sub procedure GetDataMember is added to the class module. You can see this by selecting Class from the Object list in the code editor, then selecting the Event list.

  3. Select References from the Project menu, and add a reference to the Microsoft ActiveX Data Objects 2.0 Library.

  4. Add the following to the Declarations section of the class module:
    Option Explicit
    Private rs As ADODB.Recordset
    

    This declares an object variable for the ADO Recordset object.

  5. Add the following code to the class module’s Initialize event procedure:
    Private Sub Class_Initialize()
       Dim strPath As String, strName As String
       Dim i As Integer
    
       ' Create an instance of the Recordset.
       Set rs = New ADODB.Recordset
    
       ' Set the properties of the Recordset.
       With rs
          .Fields.Append "DirID", adInteger
          .Fields.Append "Directory", adBSTR, 255
          .CursorType = adOpenStatic
          .LockType = adLockOptimistic
          .Open
       End With
    
       ' Loop through the directories and populate
       ' the Recordset. 
       strPath = "C:\"
       strName = Dir(strPath, vbDirectory)
       i = 0
       Do While strName <> ""
          If strName <> "." And strName <> ".." Then
             If (GetAttr(strPath & strName) And _
                vbDirectory) = vbDirectory Then
                i = i + 1
                With rs
                   .AddNew
                   .Fields.Item("DirID") = i 
                   .Fields.Item("Directory") = strName
                   .Update
                End With
             End If
          End If
          strName = Dir
       Loop
    
       ' Return to the first record.
       rs.MoveFirst
    End Sub
    

    In this example we’re creating a ADO Recordset object on the fly and populating it with a list of directories. Alternatively, you could use an existing recordset by assigning to the Connect property of the ADO Recordset in the Initialize event.

  6. Select Class from the Object list in the Code Editor, then select GetDataMember from the Event list. Add the following code to the GetDataMember Sub procedure:
    Private Sub Class_GetDataMember(DataMember As String, Data As Object)
       ' Assign the Recordset to the Data object.
       Set Data = rs
    End Sub
    

    The GetDataMember procedure sets the source of the data for the class. Your data source class can provide multiple data sources by adding a Select Case statement to the GetDataMember procedure and passing in a source name in the DataMember argument.

  7. Add a new Sub procedure to provide a public method to loop through the Recordset:
    Public Sub Cycle()
       ' Cycle through the Recordset.
       rs.MoveNext
       If rs.EOF = True Then
          rs.MoveFirst
       End If
    End Sub
    

    In order to move through the recordset, we need to expose the navigation methods for our class. For simplicity, this example can only loop forward through the recordset. To make the class more useful, you might want to expose methods such as MoveFirst, MoveNext, Add, and Delete.

Using the Source Class

Now that the source class is defined, we can do something useful with it. In this example we’ll bind it to a TextBox control so that we can see its output; we’ll also use a CommandButton to execute our Cycle method.

  1. Select Form1 and add a TextBox control and a CommandButton control to the form.

  2. In the Properties window, set the properties of the TextBox as follows:
    Property Setting
    Name txtConsumer
    Text (blank)

  3. In the Properties window, set the properties of the CommandButton as follows:
    Property Setting
    Name cmdCycle
    Caption Cycle

  4. Select References from the Project menu, and add a reference to the Microsoft Data Binding Collection.

    The DataBinding object provided by the Data Binding Collection is the "glue" that binds a data source to a data consumer.

  5. Add the following to the Declarations section of the class module:
    Option Explicit
    Private objSource As MySource
    Private objBindingCollection As BindingCollection
    

    We need to declare our source class (MySource) and the BindingCollection object using early binding.

  6. Add the following code to the Form_Load event procedure:
    Private Sub Form_Load()
       Set objSource = New MySource
       Set objBindingCollection = New BindingCollection
    
       ' Assign the source class to the Binding
       ' Collection’s DataSource property.
       Set objBindingCollection.DataSource = objSource
       ' Add a binding.
       ObjBindingCollection.Add txtConsumer, "Text", "Directory"
    

    In the Load event we create instances of the source class and the BindingCollection object, then we assign the source object to the DataSource property of the BindingCollection. Finally, we add a binding by specifying the name of the consumer (txtConsumer), the Property of the consumer to be bound (the Text property), and the Field property of the source object that we are binding to (Directory).

  7. Add the following code to the cmdCycle Click event procedure:
    Private cmdCycle_Click()
       ' Call the Cycle method of the data source.
       ObjSource.Cycle
    End Sub
    

    This will execute the Cycle method of our source class.

    
    
  8. Press F5 to run the project.

    As you click the Cycle button, directory names from the recordset created in our source class will appear in the TextBox. Congratulations — you’ve just bound a control to a data source class without using a Data control!

  9. Save the project. When prompted for filenames, use the following names.

    Save the source class as "MySource.cls".

    Save the form as "Dataform.frm".

    Save the project as "Dataware.vbp".

    These files will be used later in "Creating a Data Consumer."

In the next section "Creating a Data Consumer," we’ll look at the process of creating a data-aware class that acts a consumer of data.