Tutorials - True DataControl > Tutorial 5 - Implementing Master-Detail Relationships |
In this tutorial, you will learn how to implement master-detail relationships between TData controls. In this tutorial and the two that follow, you will discover how extensive and flexible the True DataControl master-detail relationship is, and how it allows you to express almost any imaginable link between different data sources in your application, without writing a line of Visual Basic code.
Start a new project.
Place the following controls on the form (Form1) as shown in the figure: two TData controls (TData1, TTData2), a DataCombo control (DataCombo1; you need to include Microsoft DataList Controls 6.0 (OLEDB) into the project’s list of components), and a DataGrid control (DataGrid1).
Open the True DataControl property pages for TData1. On the DataSource property page select 1 - Memory Array in the DataMode combo box.
Select the Fields property page. Click the right mouse button over the fields list area and select New Field from the menu (alternatively, you can press the New button). A new field with the default name FIELD_0 appears. Change the name to CustomerID by typing it in the Name text box. Select 1 - Immediate in the Modification Mode combo box for the CustomerID field. Press the OK button to close the dialog and save changes.
Set the properties of the other controls as follows (you can use the DataSource property page to set TData data source properties, as described in Tutorial 2):
Example Title |
Copy Code
|
---|---|
TData2.ConnectionString Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=C:\Program Files\ComponentOne Studio\Common\TDDEMO.MDB TData2.CommandType 2 – adCmdTable TData2.RecordSource Orders TData3.ConnectionString Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=C:\Program Files\ComponentOne Studio\Common\TDDEMO.MDB TData3.CommandType 2 – adCmdTable TData3.RecordSource Customers DataCombo1.DataSource TData1 DataCombo1.DataField CustomerID DataCombo1.RowSource TData3 DataCombo1.ListField CompanyName DataCombo1.BoundColumn CustomerID DataCombo1.Style 2 - dbcDropDownList DataGrid1.DataSource TData2 |
Note: The use of a DataCombo control is not essential for the True DataControl feature (master-detail) demonstrated in this tutorial. It is meant to make the example more realistic as an application. The TData3 control’s only purpose is to serve as the RowSource for DataCombo1. |
Open the True DataControl property pages for TData2. On the General page select TData1 in the Master combo box. This creates a master-detail relationship making TData1 the master and TData2 its dependent control (detail). This means TData2 data is dependent on TData1; therefore, each time TData1 is repositioned or one of its fields changes value, the TData2 data is re-retrieved (the control is refreshed).
Open the True DataControl property pages for TData2. Go to the Fields page. Select the CustomerID field. Click the right mouse button over the CustomerID field, and select New Range Condition from the menu (or use the New button). An empty range condition for the CustomerID field appears with controls for entering the condition now visible in the right part of the Fields property page. Go to the Value Expression text box. (You can ignore the Condition text box for now. This is for entering an optional condition specifying whether to apply the range expression or to skip it.) Press the ellipsis button to open the expression editor. You should already know how to use it from Tutorial 4.
Select master: TData1 in the From combo box. The single field of TData1 is displayed in the Fields list box. Double-click it to paste TData1.CustomerID into the expression text. Select OK to close the expression editor. The expression TData1.CustomerID will appear in the Value Expression text box. Note that you can also type directly into the text box if you prefer.
Clear the Skip If Empty check box, which is checked by default. The Comparison Operator is "=" by default, which is what we will use. This concludes the specification of our range condition. The range condition you have just entered tells TData2 to include only records in which the value of CustomerID is equal to the value of the CustomerID field of TData1.
Note: The Fields list is empty when you select self: TData2 in the From combo box of the expression editor. This means that the fields of the TData2 control itself cannot be used in its range conditions. You can only use the control’s parameters (discussed in Tutorial 7) or the fields of an ancestor TData control ("ancestor" means master, master’s master, etc.). Range expressions are evaluated before the recordset is built, so field contents and the current record position are undetermined at that time. Conversely, fields have definite values only when the recordset is ready and positioned on a certain record. This means that fields are undetermined at the moment of range condition evaluations. Range condition expressions belong to the recordset level, as opposed to, for example, calculated expressions, which belong to the record level. Field values are known at the record level and unknown at the recordset level. Each kind of True DataControl expression belongs to either the recordset or record level. |
When you choose a customer in the DataCombo1 combo box, the entire contents of DataGrid1 is updated and includes only orders placed by the selected customer. This describes how the range condition CustomerID = TData1.CustomerID works.
The grid is initially empty. This is because we cleared the Skip If Empty check box as part of our range condition. If this box is checked (the default setting), then the range condition is ignored when one of the variables on which it depends is empty. The feature is described further in Tutorial 6.
Notice that because we specified Modification Mode as 1 - Immediate for the CustomerID field of TData1, DataGrid1 is updated immediately whenever DataCombo1 changes.
Note the use of a TData control (TData1) to store the value of CustomerID in memory. In theory, a DataCombo could be placed on the form and a handler written for its Change control event that would refresh DataGrid. You could define a parameter in TData2 and set its value from code. Then you could refer to that parameter in a range condition. However, in most cases you can avoid writing Visual Basic code altogether by using memory array-based TData controls, making variable values available to other TData controls through master-detail relationships. This enables you to implement the necessary logic using design-time expressions instead of resorting to code, making it easier to maintain and much more reliable. True DataControl will generate the right sequence of operations, and will always update necessary variables.
Close the program. You have successfully completed Tutorial 5!