Starting with VB6, you can create an ActiveX control that functions as a data
source. A data source control furnishes fields from a Recordset to which other
controls can bind. Examples of data source controls that come out-of-the-box with
VB would be the traditional Data Control and the ActiveX Data Control (discussed
in Chapter 8
The minimum that you'll need to do to implement a control as a data source
Set the UserControl's DataSourceBehavior property.
Program the UserControl's GetDataMember event to return a reference
to a Recordset object. This event fires whenever a data consumer (usually a bound
control) has its DataSource property set to point to the data
These two steps are enough if your data control's behavior will be very
tightly constrained; that is, programmers who use the data source cannot determine the type
of data connection nor the data that the data source exposes. In this restricted scenario,
the GetDataMember event procedure will connect to a hard-coded set of
records in a hard-coded database using a hard-coded data driver. However, you may want to give programmers
of your data source more choice about how the control connects to data. In that case you'll
want to give programmers more of the features that standard Microsoft data source controls
Properties that allow the programmer to specify connect strings and the text of
queries that retrieve data to create specific recordsets. The GetDataMember
event procedure would then dynamically read these properties to initialize and
return the Recordset.
A Recordset property so that programmers can directly manipulate your data source
control's Recordset in their own code.
The GetDataMember Event
The GetDataMember event occurs when the
DataSource property of a data consumer that depends on the current control is set.
The purpose of this event is to return a reference to a valid Recordset object via its second parameter.
This Recordset then becomes available to the data consumer that caused the event to fire
in the first place. In Listing 13.17, the code in a GetDataMember event
procedure always returns a reference to the Recordset of the Employees
table in the Nwind Access database.
THE GETDATAMEMBER EVENT PROCEDURE
Private Sub UserControl_GetDataMember(DataMember
As String, Data As Object)
On Error GoTo GetDataMemberError
' rs and cn are Private
variables of the UserControl
' if this is the first
time through, then they haven't been set
If rs Is Nothing Or cn Is
Create a Connection object and establish
Set cn =
Create a RecordSet object.
Set rs =
"employees", cn, adOpenKeyset, adLockPessimistic
Set Data = rs
MsgBox "Error: "
& CStr(Err.Number) & vbCrLf & vbCrLf
Note in the listing that you manipulate two Private UserControl
variables: A variable representing the ADO Connection and another representing the
ADO Recordset. The event procedure code only has to set them up on the first pass through
the procedure. Once the connection and the Recordset are initialized, you skip the initialization
At the end of the routine (just before the Exit Sub to
detour around the error handler), the code assigns the Recordset to the second parameter, Data.
This in effect returns the Recordset to whatever data consumer has just requested it (typically
another control that has just had its DataSource property set to point to an
instance of this control).
Steps to Create a Data Source Control
The following steps will implement a fully functioning data source control:
STEP BY STEP
13.4 Creating a Data Source Control
Create a new ActiveX control project.
Set a reference in the project to the appropriate data library through the
Project, References menu dialog box.
Set the UserControl's DataSourceBehavior
property to 1-vbDataSource.
Create property procedures for custom properties that programmers will use
to manipulate the data source control's connection to data. Typically, you'll
implement String properties such as ConnectString
(connection string to initialize a Connection object) and
RecordSource (string to hold the query to initialize the data in the recordset).
Create private variables to hold the values of each of the properties. Create
private constants to hold their initial default values. Program the InitProperties,
ReadProperties, and WriteProperties event procedures
to persist these properties.
If you want to expose the control's Recordset for other programmers to manipulate,
then you should create a custom property name, RecordSet. Its type will be the
appropriate Recordset type that you plan to program for your control. You may
choose to make it read-only, in which case you only need to give it a
Property Get procedure. Declare a private object variable to hold its value
using WithEvents (this exposes the event procedures
to other programmers).
Declare a Private variable of the appropriate connection type that you plan
to program for your control. It will not correspond to a custom property, but
it's necessary in order to host the Recordset.
Code the InitProperties, ReadProperties, and
WriteProperties events to properly manage and persist the values of the
properties created in the previous steps.
Program the UserControl's GetDataMember
event procedure to initialize a recordset and return it in the second parameter.
You will derive the Recordset either from information contained in custom
Private variables or from hard-coded information in the
GetDataMember event procedure itself (see the previous section for an example).
You should perform some errortrapping to ensure that you do indeed have a valid
Put code in the UserControl's
Terminate event that will gracefully close the data connection.
If you want to allow users to navigate data by directly manipulating your
UserControl, then put the appropriate user interface on your
UserControl along with the code to navigate the Recordset variable.
Your new ActiveX control should now be ready to test as a
DataSource:Add a standard EXE project to the Project Group. Now, making
sure you've closed the designer for the UserControl, add
an instance of your new control to the standard EXE's form.
Manipulate any necessary custom properties (such as ConnectString
or RecordSource) that you may have put in your
Put one or more bindable controls in the test project and set their
DataSource property to point to the instance of your Data Source Control.
Set their DataField properties to point to fields from
the exposed Recordset.