H o m e
G e t    B e t t e r    A c q u a i n t e d    w i t h    t h e    D a t a V i e w    C l a s s

 

By Michael McIntyre

mikemc@getdotnetcode.com

 

The DataView class is very important to every ADO.NET programmer. Don’t overlook the necessity, flexibility, and power of the DataView class.

 

Consider this important fact: When a DataTable is bound to a form control, a DataView object is used as a “middleman” - whether the programmer explicitly codes it or not. If you do not code it, the binding process uses the DataTable’s default DataView behind the scene. Here is a simple diagram showing the relationship that is established when a DataTable is bound to a DataGrid control:

 

DataTable <-> DataView <-> DataGrid

 

Because of the relationship shown above you must understand the role the DataView “middleman” plays in binding to master DataTable-to-form control binding. To sort, filter, search, edit, or navigate a DataTable bound to form controls, a DataView is the best object for the job. For example, using the DataView “middleman” to access and manipulate a DataTable bound to a Windows Forms DataGrid is more effective than the round-about approach of using the properties and methods of the DataGrid.

 

This article will help you understand and learn how to make the DataView “middleman” work to your advantage when binding DataTables to Windows Forms controls.

 

.NET Help Defintion: DataView Class

 

“A DataView represents a databindable, customized view of a DataTable for sorting, filtering, searching, editing, and navigation.”

 

Basic DataView Concepts

 

A DataView object provides a view of the rows contained in one DataTable object.  Only one DataTable is assigned to a DataView. The resulting view can be sorted, filtered, and searched. The DataTable assigned to the DataView can be edited and navigated through the view.

 

A major function of the DataView is to allow a DataTable to be bound to both Windows Form controls. A DataTable is bound to Windows control(s) through a DataView.

 

If you do not know that a DataView gets placed between a DataTable and a form control during binding, it may have seemed that you have been binding your DataTables directly to form controls. After all, you can write code like this that appears to directly bind a DataTable to a DataGrid:

 

DemoDataGrid.DataSource = DemoDataSet.Tables("Product")

 

However, when the code above is run, behind the scenes .NET will retrieve the Product table’s DefaultView (a DataView) and bind the DemoDataGrid control to that DataView, not directly to the Product table. In other words, if you do not provide a DataView object for binding a DataTable to a form control, .NET will use that DataTable’s DefaultView to complete the binding.

 

Demonstration One

 

This first DataView demonstration will show how to explicitly bind a DataTable’s DefaultView to a DataGrid and how to sort the DefaultView to change the order of the data shown in the DataGrid.

 

For demonstration purposes please assume the following things exist:

 

1.  A DataSet named DemoDataSet

2.  In DemoDataSet a DataTable named Product

3.  In Product DataTable this data:

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

3

Green Bean

Vegetable

4

Spinach Noodle

Pasta

 

4.  A Windows Form named ProductForm

5.  On the ProductForm a DataGrid named ProductDataGrid

 

EXAMPLE: Create a DataView variable and to it assign the Product table’s DefaultView.

 

' Declare a variable of type DataView named _ProductDataView.

' Assign DemoDataSet’s Product table’s DefaultView to the _ProductDataView variable.

Dim _ProductDataView As DataView = _

AppMgr.DemoDataSet.Tables("Product").DefaultView

 

EXAMPLE: Make _ProductDataView the DataSource for the ProductDataGrid.

 

' Set the ProductDataGrid's DataSource

' to _ProductDataView.

ProductDataGrid.DataSource = _ProductDataView

 

EXAMPLE: Run the ProductForm.  The ProductDataGrid will show:

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

3

Green Bean

Vegetable

4

Spinach Noodle

Pasta

 

EXAMPLE: Sort the _ProductDataView by setting the DataView object’s Sort property.

 

' Sort _ProductDataView to change

' the order of the data presented in the ProductDataGrid.

_ProductDataView.Sort = "ProdName"

 

Result: ProductDataGrid shows Product data sorted by ProdName.

 

ProdId

ProdName

ProdCategory

2

Apple

Fruit

1

Banana

Fruit

3

Green Bean

Vegetable

4

Spinach Noodle

Pasta

 

 

Demonstration Two

 

This demonstration will shhow to use a DataView object to filter, search, and navigate, a DataTable.

 

EXAMPLE: Filter _ProductDataView by setting the DataView object’s RowFilter property.

 

' Filter _ProductDataView to show

' only the ‘Fruit’ ProdCategory in the  ProductDataGrid.

_ProductDataView.RowFilter = "ProdCategory = 'Fruit'

 

Result: ProductDataGrid shows only products where ProdCategory = Fruit

 

ProdId

ProdName

ProdCategory

2

Apple

Fruit

1

Banana

Fruit

 

EXAMPLE: Find row using the DataView object’s Find method.

 

' Clear RowFilter.

Me._ProductDataView.RowFilter = ""

' To use the DataView's Find method the column(s)

' to be searched must be sorted.

Me._ProductDataView.Sort = "ProdId"

' Declare a variable of type Integer named recordIndex.

Dim recordIndex As Integer = -1

' Find the _ProductDataView row where ProdId = 1

recordIndex = Me._ProductDataView.Find(1)

' If the record was found...

If recordIndex > -1 Then

       ' Show the name of Product row found.

       MessageBox.Show(Me._ProductDataView(recordIndex)("ProdName").ToString)

End If

 

Result:  Banana

 

EXAMPLE: Find rows using the DataView object’s FindRows method.

 

' Clear RowFilter.

Me._ProductDataView.RowFilter = ""

' To use the DataView's FindRows method the column(s)

' to be searched must be sorted.

Me._ProductDataView.Sort = "ProdCategory"

' Declare a variable of type DataRowView Array named productRowViews.

' Call FindRows on _ProductDataView to get rows where

' ProdCategory = Fruit.

Dim productRowViews() As DataRowView = Me._ProductDataView.FindRows("Fruit")

' If one or more rows were found....

If productRowViews.Length > 0 Then

    ' Loop through the productRowViews array.

    Dim dataRowViewType As DataRowView

    For Each dataRowViewType In productRowViews

       MessageBox.Show(dataRowViewType("ProdName").ToString)

    Next

End If

 

Result: 

 

Banana

Apple

 

EXAMPLE:  Navigate DataGrid rows through a DataView.

 

Assume current row selected in Product DataGrid is row one.

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

3

Green Bean

Vegetable

4

Spinach Noodle

Pasta

 

' Declare a variable of type BindingManagerBase named bindingManager.

Dim bindingManager As BindingManagerBase

' Assign _ProductDataView's BindingContext to bindingManger.

bindingManager = BindingContext(Me._ProductDataView)

' Move forward one row.

bindingManager.Position += 1

 

Result: Row two is now the selected row in ProductDataGrid

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

3

Green Bean

Vegetable

4

Spinach Noodle

Pasta

 

Here are code examples to navigate to the First, Next, Previous, and Last rows in a DataView.

 

' Move to first row in DataView

bindingManager.Position = 0

 

' Move forward one row.

bindingManager.Position += 1

      

' Move back one row.

bindingManager.Position -= 1

       

' Move to last row in DataView.

bindingManager.Position = Me._ProductDataView.Count – 1

 

Demonstration Three

 

This demonstration uses a DataView object to insert, modify, and delete rows in a DataTable.

 

 

EXAMPLE: Insert a new row in a DataTable.

 

' Insert a DataRow into a DataTable.

' Declare a variable of type DataRow named newDataRow.

Dim newDataRow As DataRow

' Call the Product DataTable's NewRow method to create a new DataRow.

' Assign the resulting DataRow object to the newDataRow variable.

newDataRow = Me._ProductDataView.Table.NewRow

' Fill in columns in the new DataRow with data.

' Use strings to refer to columns by column name.

newDataRow("ProdName") = "Frozen Peas"

newDataRow("ProdCategory") = "Frozen Foods"

' After a programmatic insert, modification, or delete of a row

' always call the row's EndEdit method.

newDataRow.EndEdit()

' Add the new DataRow to the Product DataTable.

Me._ProductDataView.Table.Rows.Add(newDataRow)

 

Result (Frozen Peas row is added)

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

3

Frozen Peas

Frozen Foods

 

 

EXAMPLE:  Use a BindingManagerBase object to get a reference (pointer) to the current  DataRow in a binding between a DataView and a DataTable.  To modify or delete a DataRow in the source DataTable behind a DataView, you must first get a pointer to DataRow.  This function is called by the modify and delete DataRow examples that follow.

 

Private Function GetCurrentDataRow() As DataRow

   ' Declare a variable of type DataRow named sourceTableDataRow.

   Dim sourceTableDataRow As DataRow

   ' Cast the BindingManagerBase's Current(row) as a DataRowView.

   ' Cast the DataRowView as a DataRow.

   ' Assign the resulting reference to the sourceTableDataRow variable

   ' which is now a pointer to the original row the source table.

   sourceTableDataRow = CType(CType(Me._BindingManager.Current, DataRowView).Row,    DataRow)

   ' Return a reference (pointer) to the source DataRow.

   Return sourceTableDataRow

End Function

 

 

EXAMPLE: Use a DataView to modify a row in a DataTable.

 

' Modify a DataRow in the source DataTable behind a DataView.

' Declare a variable of type DataRow named curDataRow.

' Call the GetCurrentDataRow method.

' Assign the address (reference) returned

' to the curDataRow variable.

Dim curDataRow As DataRow = Me.GetCurrentDataRow

' Modify columns in the DataRow.

' Use strings to refer to columns by column name.

curDataRow("ProdName") = curDataRow("ProdName").ToString & " Modifed: " & DateTime.Now.ToLongTimeString

' After a programmatic insert, modification, or delete on a row

' always call the row's EndEdit method.

curDataRow.EndEdit()

 

Result (code above called with the Frozen Peas row selected)

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

3

Frozen Peas Modifed: 7:37:53 PM

Frozen Foods

 

 

EXAMPLE: Use a DataView to delete a row in a DataTable.

 

' Delete a DataRow from the source DataTable behind the DataView.

' Declare a variable of type DataRow named curDataRow.

' Call the GetCurrentDataRow method.

' Assign the address (reference) returned

' to the curDataRow variable.

Dim curDataRow As DataRow = Me.GetCurrentDataRow

' Call the DataRow's Delete method.

curDataRow.Delete()

' After a programatic insert, modification, or delete on a row

' always call the row's EndEdit method.

curDataRow.EndEdit()

 

Result (code above called with the Frozen Peas row selected)

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

 

Demonstration Four

 

This demonstration explains 1) how to use the DataView AllowNew, AllowEdit, and AllowDelete properties; 2) how to create and use multiple views of the same DataTable; and 3) the DataViewManager class.

 

The DataView AllowNew, AllowEdit, and AllowDelete Methods

 

Being the middleman between the Product DataTable and the ProductDataGrid, the Product DataTable’s DefaultView can used to allow/disallow inserts, edits, and deletes in the ProductDataGrid.


Example:  Control inserts, edits, and deletes with a DataView.

 

' Disallow inserts, allow edits, disallow deletes.

_ProductDataView.AllowNew = False

_ProductDataView.AllowEdit = True

_ProductDataView.AllowDelete = False

 

Use Multiple Views of the Same DataTable

 

Two or more DataViews can be customized to present different views of data from the same DataTable. For example, one DataView may show the rows of a DataTable sorted one way, while a second DataView displays the same rows sorted a different way.

 

Example:  Use two DataViews to display two different views of the Product DataTable.

 

A new DataGrid named ProductsByNameDataGrid has been added to our sample application. A second DataView is created and is used to bind the Product table to the ProductsByNameDataGrid. The new DataView is sorted by ProdName.

 

' Declare a variable of type DataView named _ProductsByNameDataView.

' Instantiate a new DataView object that is bound to the Product DataTable

' and assign it to the _ProductsByNameDataView variable.

Dim _ProductDataView As New DataView( _

AppMgr.DemoDataSet.Tables("Product")

 

' Set the ProductsByNameDataGrid’s DataSource to _ProductsByNameDataView.

ProductDataGrid.DataSource = _ProductDataView

 

' Sort the ProductsByNameDataView by ProdName.

_ProductsByNameDataView.Sort = "ProdName"

 

Result:

 

ProductDataGrid is shown in ProdId order.

 

ProdId

ProdName

ProdCategory

1

Banana

Fruit

2

Apple

Fruit

 

ProductsByNameDataGrid is shown in ProdName order.

 

ProdId

ProdName

ProdCategory

2

Apple

Fruit

1

Banana

Fruit

 

 

The DataViewManager Class

 

A DataViewManager object is mainly used for working with a DataSet that contains related tables.  A DataViewManager object contains a collection of data views, one for each table in the dataset.

 

A DataSet object has a DefaultViewManager property.  A DataSet’s DefaultViewManager can be bound to a DataGrid to bind all the DataTables in the DataSet to the DataGrid.

 

The example below uses a new scenario.  Imagine a DataSet named SalesDataSet already exists. SalesDataSet contains three related tables – Customer, Order, and OrderLine.   Imagine a DataGrid named SalesDataGrid already exists.

 

The example shows the code necessary to 1) create a DataViewManager type variable; 2) assign  SalesDataSet’s DefaultViewManager to it; and 3) use the variable to bind the SalesDataSet’s DataTables to the SalesDataGrid.

 

Example:  Use a DefaultViewManager to Bind a DataSet’s DataTables to a DataGrid.

 

' Declare a variable of type DefaultViewManager named _SalesDefaultViewManager.

' Assign SalesDataSet’s DefaultViewMananger

' to the _SalesDefaultViewManager variable.

Dim _SalesDefaultViewManager As DataViewManager = Sales.DefaultViewManager

 

' Set the SalesDataGrid's DataSource to _SalesDefaultViewManager

Me.SalesDataGrid.DataSource = _SalesDefaultViewManager

 

Result:  All of SalesDataSet’s DataTables are bound to the SalesDataGrid.

 

At this point the _SalesDefaultViewManager variable can be used to manage the DefaultViews behind the Customer, Order, and OrderLine DataTables. Here is an example that sets the sort order of the Customer DataTable.

 

' Sort the Customer DataTable’s DefaultView by Customer name.

_SalesDefaultViewManager.DataViewSettings.Item("Customer").Sort = "CustomerName"

 

NOTE: You must create and configure DataViewManagers in code; there is no design-time object for a DataViewManager.

 

To learn more about the DataView and DataViewManager classes visit the links below:

 

DataView Class  /  DataView Members  /  DataViewManager

 

Copyright © 2001-2003 aZ Software Developers. All rights reserved.