Binding a Control to a Data Source

See Also

Visual Basic allows you to mark properties of your control as bindable, allowing you to create data-aware controls. A developer can associate bindable properties with fields in any data source, making it easier to use your control in database applications.

Use the Procedure Attributes dialog box, accessed from the Tools menu, to mark properties of your control as bindable. Figure 9.9 shows the data binding options made available by clicking the dialog's Advanced button.

Figure 9.9   Data binding options for ActiveX control properties

The controls supplied with Visual Basic can be bound to data source fields using their DataSource and DataField properties. You can select one property of your control to be bound to the DataField property. Typically, this will be the most important piece of data your control holds.

Although you can mark only one field as bound to the field specified in the DataField property, you can mark additional properties of your ActiveX control as bindable. Developers can use the DataBindings collection to bind these additional bindable properties to data fields.

Note   Some development tools and control containers do not support data binding. This topic describes the support for data-bound controls provided by Visual Basic.

The DataBindings Collection

The DataBindings collection is an extender property that Visual Basic provides to users of your control. It allows the developer to access the list of bindable properties on your control.

Note   All bindable properties appear in the DataBindings collection at run time. At design time, only properties marked "Show in DataBindings collection at design time" will appear when the DataBindings property is accessed in the Properties window.

For example, you might create an Address control assembly, using labels and text boxes as constituent controls. The bindable properties of your control would correspond to the text boxes on your control, as shown in Figure 9.10.

Figure 9.10   An Address control assembly with multiple fields

Note   If your control has multiple bindable properties, you must mark one as binding to the Extender object's DataField property. Otherwise, the Extender object will not provide a DataSource property for your control. You can mark a property as binding to DataField by selecting "This property binds to DataField" in the Procedure Attributes dialog box. The property you mark as binding to DataField can also be bound using the DataBindings collection.

The mapping between properties of the control and contents of the constituent controls is accomplished by delegation, as in this code fragment:

Public Property Get AddressLine1() As String
   AddressLine1 = txtAddressLine1.Text
End Property

Public Property Let AddressLine1(NewValue As String)
   If CanPropertyChange("AddressLine1")
      txtAddressLine1.Text = NewValue
      ' The following line tells Visual Basic the
      ' property has changed--if you omit this line,
      ' the data source will not be updated!
      PropertyChanged "AddressLine1"
   End If
End Property

Delegating to the text box control means that the text box does all the work of displaying the value and accepting user changes. Because the user can change the value of the property while the text box is displaying it, you must also mark the property as changed in the text box's Change event, as shown below.

Private Sub txtAddressLine1_Change()
   PropertyChanged "AddressLine1"
End Sub

Important   In order for the new value to be written back to the data source, you must call PropertyChanged. If you don't call the PropertyChanged method, your control will not be bound for update.

For More Information   The PropertyChanged method has another important purpose, as discussed in "Adding Properties to Controls," later in this chapter.

Calling CanPropertyChange

Your control should always call CanPropertyChange before changing the value of a property that can be data-bound. Do not set the property value if CanPropertyChange returns False. Doing so may cause errors in some control containers.

If your control always calls CanPropertyChange, you can check "Property will call CanPropertyChange before changing" on the Procedure Attributes dialog box.

Note   At present, CanPropertyChange always returns True in Visual Basic, even if the bound field is read-only in the data source. This does not cause a problem with the code shown above, because Visual Basic doesn't raise an error when your program attempts to change a read-only field; it just doesn't update the data source.

Discovering and Setting Bindable Properties at Run Time

If a developer placed an instance of the AddressBox control on a form, she could execute the following code to list the bindable properties:

   Dim dtb As DataBinding
   For Each dtb In AddressBox1.DataBindings
      Debug.Print dtb.PropertyName
   Next

At run time, the developer could use the following code to bind the AddressLine1 property to the AddrLine1 field, assuming that field was available on the data source specified by the DataSource extender property:

   AddressBox1.DataBindings( _
      "AddressLine1").DataField = "AddrLine1"

Finding Out Whether a Field has Changed

You can test the DataChanged property of a DataBinding object to find out if the value of a field has changed. This property functions in the same way as the DataChanged extender property of bound controls.

Setting Multiple Data Bindings at Design Time

Bindable properties always appear in the DataBindings collection at run time. By default, they do not appear in the Data Bindings dialog box at design time.

If you want a bindable property to appear in the Data Bindings dialog box, select that property in the Procedure Attributes dialog box and check "Show This Property in the Bindings Collection."

Figure 9.11   Using the Data Bindings dialog box

The Data Field box shows all fields available on the data source specified by the current value of the DataSource extender property on the control instance.

Attributes and Flags

If you have developed OLE controls in the past, you can use the following table to see what flags are set by the Procedure Attributes dialog box. The table also shows how these attributes are accessed through the Member object in the Visual Basic Extensibility Model.

Attribute Flag Member Object
Property is data bound. BINDABLE Bindable
This property binds to DataField. DEFAULTBIND DefaultBind
Show in DataBindings collection at design time. DISPLAYBIND DisplayBind
Property will call CanPropertyChange before changing. REQUESTEDIT RequestEdit