The binding model

The binding model allows you to bind the data in a DataTable to a DataWindow in the same way you would bind the data to a DataGrid. When a DataWindow is bound to a DataTable or to a DataView, modifications to the data are applied immediately to the underlying object. Modifications to the underlying object (from other bound controls for example) are reflected immediately in the DataWindow. When a DataWindow is bound to a DataTable, it binds to the “default view” of the DataTable.

You cannot use DataWindow methods such as Retrieve and Update because they duplicate features of the underlying object. For example, the DataWindow does not populate the DataSet with data. To populate the DataSet, use the Fill method of a DataAdapter.

The following C# statements populate the DataSet described in “Using a DataSet as the data source”, creating two DataTables:

DepartmentAdapter.Fill ( DeptEmployee );
EmployeeAdapter.Fill ( DeptEmployee );

These statements populate the DataWindow and a DataWindowChild, in this case a drop-down DataWindow, from the DataTables:

DataWindowChild DDDW = dw1.GetChild( "dept_head_id" );
DDDW.BindAdoDataTable ( DeptEmployee.employee );
dw1.BindAdoDataTable ( DeptEmployee.department );

DataView methods

These statements delete a row from a DataView:

DataRowView DRV = DepartmentView[1];
DRV.Delete ( );
DRV.EndEdit( );

This statement inserts a blank row into the DataView:

newRow = DepartmentView.AddNew ( );

The row will not appear in the DataWindow until the EndEdit method has been called and has completed.

These statements change a specific column's data value. You use them instead of the SetItem methods of the DataWindow control:

DataRowView DRV = DepartmentView [ 0 ];
DRV [ 0 ] = "800";
DRV.EndEdit();

In the preceding examples, the EndEdit method is required because we use the DataView ListChanged event to signal changes to the DataView. In most cases the data is not available for copy to the DataWindow until the EndEdit method is complete. For example, in the following example, three ListChanged events occur. These statements insert a row with values into a DataView:

newRow = DepartmentView.AddNew();
newRow [ "dept_id" ] = "900";
newRow [ "dept_name" ] = "AppleWare";
newRow [ "dept_head_id" ] = "102";
newRow.EndEdit( );

First an ItemAdded event occurs when the AddNew method is called. The row has null values and is added to the end of the DataView in a detached state.

When the EndEdit method is processed, another ItemAdded event occurs. The row now has values and is added to the DataView.Finally an ItemMoved event occurs when the inserted row is moved to the correct ordinal position in the DataView.

DataWindow methods

If the user needs to specify column values for a row, you need to insert an empty row. You can use a version of the DataWindow InsertRow method without a row number specification:

dw1.InsertRow ( );

When the row is added to the DataWindow, it is added at the end of the DataWindow and the DataWindow scrolls to its location.

When you insert a row into a DataWindow, it is not propagated to the underlying DataTable or DataView immediately. Most DataTables and DataViews specify a unique key, and if that key is null, an exception is thrown. Since a row inserted into a DataWindow has no values at the time of insertion, it is not added to the DataTable until the RowFocusChanged event is fired.

When focus changes from the new row, the Binding Manager intercepts the RowFocusChanged event from the DataWindow, creates a new DataView row (DataRowView), populates it with the values from the DataWindow row, and performs an EndEdit. At this time the new row is accepted by the DataView (its RowStatus is “Added”) and it moves to the correct location in the DataView.

NoteRow number ignored If a row number is specified in the InsertRow method, it is ignored. The row is added to the end of the DataWindow.

Deleting a row from the DataWindow is typically done to remove a row added by InsertRow with incomplete data. This abandons the new row and its values before adding it to the DataView.

dw1.DeleteRow ( Int32 rowNumber );

If the row being deleted is not new, DeleteRow deletes the corresponding DataRowView in the DataView. The Binding Manager is notified of the deletion by the ListChanged event of type ItemDeleted and the corresponding DataWindow row is deleted.

Restricted DataWindow methods

To conform to the data binding model, many built-in DataWindow features are restricted. Although the normal data buffers are in place and used internally, they cannot be accessed in code so that the principles of the “data access separate from data presentation” mode are preserved. Restricted methods include:

Updating values

When a data value is changed in the user interface, the change is communicated to the DataView immediately. If the DataColumn values have changed since the BindAdoDataTable method was executed, an error is posted. If the change is to a sort key value in the DataView, the row moves to its correct position in the DataView and in the DataWindow.You need to use a DataAdapter or another technique to propagate the changed DataSet, DataTables, and/or DataView back to their data sources using the built-in methods of those objects.

Example: Binding model

This example creates two OLE DB data adapters using SQL queries that are the same as the SQL statements for a DataWindow object and a drop-down DataWindow and uses them to fill two DataSets. Then it binds the DataTables from each of the DataSets to a DataWindowControl and a DataWindowChild.

[Visual Basic]
Dim daDept as OleDbDataAdapter
Dim dsDept as New DataSet
Dim daDDDW as OleDbDataAdapter
Dim dsDDDW as New DataSet
Dim sqlStmt as String
Dim sqlDDDW as String
Dim dwc as Sybase.DataWindow.DataWindowChild


'Specify a SQL query that is the same as the DataWindow object's SQL statement
SqlStmt = "select dept_id, dept_name, dept_head_id from department"


'Specify a SQL query that is the same as the drop-down DataWindow's SQL statement
SqlDDDW = "select emp_id from employee"


'Create two OLE DB data adapters using the SQL query strings
daDept = New OleDbDataAdapter(sqlStmt,OleDbConn)
daDDDW = New OleDbDataAdapter(sqlDDDW, OleDbConn)

'Fill two DataSets
daDept.Fill(dsDept, "department")
daDDDW.Fill(dsDDDW, "employee")

'Get the DDDW 
dwc = dw1.GetChild("dept_head_id")

'Bind a DataTable to the DDDW
dwc.BindAdoDataTable(dsDDDW.Tables("employee"))

'Bind a DataTable to the DataWindowControl
dw1.BindAdoDataTable(dsDept.Tables("department"))

[C#]
OleDbDataAdapter daDept;
DataSet dsDept = new DataSet;
OleDbDataAdapter daDDDW;
DataSet dsDDDW = new DataSet;
String sqlStmt,sqlDDDW;
Sybase.DataWindow.DataWindowChild dwc;


// Specify a SQL query that is the same as the 
// DataWindow object's SQL statement
SqlStmt = "select dept_id, dept_name, dept_head_id from department";


// Specify a SQL query that is the same as the 
// drop-down DataWindow's SQL statement
SqlDDDW = "select emp_id from employee";


// Create the data adapters
daDept = new OleDbDataAdapter(sqlStmt,OleDbConn);
daDDDW = new OleDbDataAdapter(sqlDDDW, OleDbConn);


// Fill the DataSets
daDept.Fill(dsDept, "department");
daDDDW.Fill(dsDDDW, "employee");

// Get the DDDW 
dwc = dw1.GetChild("dept_head_id");

// Bind a DataTable to the DDDW
dwc.BindAdoDataTable(dsDDDW.Tables("employee"));

// Bind a DataTable to the DataWindowControl
dw1.BindAdoDataTable(dsDept.Tables("department"));