Creating Bindable Views of Data with a DataView


Creating Bindable Views of Data with a DataView

Up until now, the means by which data is extracted from a DataTable is to access the DataTable.Rows collection. Each DataRow in the DataTable.Rows collection has DataColumn objects that can be indexed by name or number. The first sample application in this chapter demonstrates the process of iterating through the DataTable.Rows collection to examine the data.

While this is an effective way of accessing the data inside a DataTable , it does not provide an easy means of sorting the data against a specific column or filtering the rows so that only specific DataRow s in the DataTable.Rows collection are visible.

The DataView class is the correct way to view the contents of a DataTable in a sorted and/or filtered format. From the outside the DataView looks very much like a DataTable . There is an indexer through which the rows in a DataView are accessible, and the DataColumn s inside each row can be accessed and manipulated in the usual way.

The DataView is also a data-bindable object. This means that it implements interfaces that allow the DataView to become the data source for other objects that can manipulate data-bindable objects. Specifically, you can use the DataView to populate a DataGrid with the contents of a DataView . After you have set up a relationship between a DataView and a DataGrid , the contents of the DataGrid are bound to the DataView . The DataGrid shows the contents of the DataGrid , and the display is automatically kept up to date when the DataView changes.

For example, you can create a DataView that sorts by the Age column of a DataTable and bind it with a DataGrid . The DataGrid displays the contents of the DataView . If the application inserts more data into the underlying DataTable , then the DataGrid updates its view automatically.

LIMITATIONS OF THE DataGrid

The DataGrid is present in the .NET Compact Framework, but it is a strongly cut-down version compared to the desktop DataGrid . The DataGrid is treated in great detail in Chapter 3, "Designing GUI Applications with Windows Forms." Instructions on how to perform data binding with a DataGrid and a DataView are given in the "Binding to a DataGrid" section later in this chapter.


Sorting with the DataView

To sort the data in a DataTable using a DataView , follow these steps:

  1. Create a new DataView .

  2. Set the Sort property of the newly instantiated DataView . The Sort property is a string that states which columns to sort by. Add the term DESC to sort a column in descending order and separate the columns with a comma.

The following sample code is pulled from the DataView_Sort_And_Filter sample application. It creates a new DataView from the first table in a DataSet . It sorts by age in descending order, then by name in descending order as a secondary sort key. Finally, it inserts the DataRow s, which are now sorted, into a ListBox.

 
 C# DataView l_sortAgeView = new DataView(in_DataSet.Tables[0]); l_sortAgeView.Sort = "Age DESC, Name DESC"; for (int i = 0; i < l_sortAgeView.Count; i++) {    this.listBox2.Items.Add(l_sortAgeView[i]["Name"] + "   " +            l_sortAgeView[i]["Age"]); } VB Dim l_sortAgeView As DataView l_sortAgeView = New DataView(in_DataSet.Tables(0)) l_sortAgeView.Sort = "Age DESC, Name DESC" Dim i As Integer For i = 0 To l_sortAgeView.Count - 1    Me.listBox2.Items.Add(l_sortAgeView(i)("Name") + "   " +            Convert.ToString(l_sortAgeView(i)("Age"))) Next i 

Sorting and Filtering Data in a Sample Application

The sample application called DataView_Sort_And_Filter demonstrates how to use a DataView to sort and filter the contents of a DataTable . The source code is located in SampleApplications\ Chapter6\DataView_Sort_And_Filter_CSharp and DataView_Sort_And_Filter_VB .

This simple application creates a DataSet with a single table. The table rows hold an entry for a name and an age. The table is populated with six entries.

The main window has three ListBoxes. The topmost ListBox shows the contents of the DataTable as they are stored in the DataTable . The middle ListBox shows the contents of a DataView that is configured to sort the entries in the DataTable by age in descending order, and then by name in descending order as a secondary sort key. That is, if two entries have the same age, then they are alphabetically sorted in descending order by their names . The entries in the DataSet are doctored so that it is obvious that sorting occurs.

The bottom ListBox shows the contents of a DataView configured with a filter so that it shows only entries whose age is 21 or greater.

Tracking Changes in a DataRow

Every DataRow pulled from a DataTable or a DataView has a property called RowState . The RowState is of type DataRowState , which has one of nine possible values:

Unchanged This DataRow has not been changed since the last time AcceptChanges was called on the DataSet that owns the DataRow .

Original Refers to all original rows that are either unchanged or were deleted since the last time AcceptChanges was called on the DataSet that owns the DataRow .

CurrentRows All of the rows available in the DataRow or DataView , regardless of whether they are newly added, deleted, or modified since the last time AcceptChanges was called on the DataSet that owns the DataRow . If the rows have been modified, this value refers to the modified value.

Added This DataRow has been added to the DataTable.Rows collection since the last time AcceptChanges was called on the DataSet that owns the DataRow .

Deleted This DataRow has been deleted from the DataTable.Rows collection since the last time AcceptChanges was called on the DataSet that owns the DataRow .

ModifiedCurrent Refers to the current data in rows that have been modified since the last time AcceptChanges was called on the DataSet that owns the DataRow .

ModifiedOriginal Refers to the original data of DataRow s that have been modified since the last time AcceptChange s was called on the DataSet that owns the DataRow .

None Refers to none of the DataRow s.

Detached This DataRow is not part of the DataTable.Rows collection. This happens, for example, if the DataRow is created but never added to the collection.

Filtering with the DataView

There are situations in which it would be useful to filter the rows in a DataTable such that, for example, it shows only those rows that have been modified in some way. This is easy to do using the DataView . To set up a DataView to filter the data according to its RowState status, set the DataView.RowStateFilter property to one of the DataRowState values discussed in the preceding list.

DataSet.AcceptChanges COMMITS ALL CHANGES

Remember that calling DataSet.AcceptChanges commits to changes made to the data, such as adding, removing, or modifying DataRow s.


The following code demonstrates how to use the DataRowState to show only those rows that have been added since the last call to AcceptChanges() . The code is taken from the DataView_SortByRowState_AddTables sample application:

 
 C# // This DataView shows only rows that have been added since // the last call to AcceptChanges m_addedRowsView = new DataView(l_DataSet.Tables[0]); m_addedRowsView.RowStateFilter = DataViewRowState.Added; VB ' This DataView shows only rows that have been added since ' the last call to AcceptChanges m_addedRowsView = New DataView(l_DataSet.Tables(0)) m_addedRowsView.RowStateFilter = DataViewRowState.Added 

MATCHING MULTIPLE RowState VALUES IN A DataView

To view DataTable s that match different DataRowState values, or those values togetherfor example, to view deleted and newly added rows onlyuse the following code:

 
[View full width]
 
[View full width]
C# l_DataView.RowStateFilter = DataViewRowState.Added graphics/ccc.gif DataViewRowState.Deleted; VB l_DataView.RowStateFilter = DataViewRowState.Added Or graphics/ccc.gif DataViewRowState.Deleted

Adding Data into a DataView

New DataRow s can be added to a DataView and then percolated back to the source DataTable . This can be a convenient feature in business applications that manipulate their data almost exclusively through DataView classes. To add a new DataRow to an existing DataView and percolate it back to the original DataTable, follow these steps:

  1. Create an instance of DataRowView by calling DataView.AddNew() on the DataView that is being used to add a new row.

  2. Insert values for the DataColumn s of the DataRowView. The DataRowView can index its DataColumn s only by the column name.

  3. Call DataRowView.EndEdit() . This signals that you have finished setting up the new DataRowView but does not call AcceptChanges on the parent DataSet .

The following sample code demonstrates how to add data using a DataView . The code is borrowed from the sample application DataView_SortByRowState_AddTables, which is described in detail in the next section. It uses an instance of the Random class to provide pseudo-random integers to append to the name of the person and for the age of the person.

 
 C# int l_maxRandom = 100; // Step 1 - Create instance of the DataRowView DataRowView l_firstNewDataRowView = m_addedRowsView.AddNew(); // Step 2 - Set column values l_firstNewDataRowView["Name"] = "NewPerson" +         m_Random.Next(l_maxRandom).ToString(); l_firstNewDataRowView["Age"] = m_Random.Next(l_maxRandom).ToString(); // Step 3  call EndEdit() l_firstNewDataRowView.EndEdit(); VB Dim l_maxRandom As Integer l_maxRandom = 100 ' Step 1  Create instance of the DataRowView Dim l_firstNewDataRowView As DataRowView l_firstNewDataRowView = m_addedRowsView.AddNew() ' Step 2  Set column values l_firstNewDataRowView("Name") = "NewPerson" +         m_Random.Next(l_maxRandom).ToString() l_firstNewDataRowView("Age") = m_Random.Next(l_maxRandom) ' Step 3  call EndEdit() l_firstNewDataRowView.EndEdit() 

Using a DataView in a Sample Application: DataView_SortByRowState_AddTables

The DataView_SortByRowState_AddTables sample application is located in the folder \SampleApplications\Chapter6\ . There is a C# and a Visual Basic version. It demonstrates filtering DataRow s based on their RowState values and adding tables to a DataView .

The application starts by creating and populating a DataSet with a single DataTable . The DataTable schema has DataColumn s called Name and Age . The application fills the DataTable with six records and creates two DataView classes. One DataView reveals only those records that have been deleted since the last call to AcceptChanges , while the other reveals only those records that have been added since the last call to AcceptChanges .

There are three ListBoxes. The first is painted with data directly from the DataTable . Only those DataRow s with RowState value set to Unchanged are painted into the ListBox. The second ListBox is painted with data from the DataView that reveals the added rows. The third ListBox is painted with data from the DataView that reveals the deleted rows.

When the application first launches, there are no added or deleted rows, so only the topmost ListBox shows any entries. Clicking the button labeled Add and Delete some rows causes two rows to be deleted from the DataTable and two rows to be added to the m_AddedRowsView DataView by using the code in Listing 6.2:

Listing 6.2 Adding and deleting DataRows through a DataView
 C# // Delete two rows m_DataSet.Tables[0].Rows[0].Delete(); m_DataSet.Tables[0].Rows[1].Delete(); // Add two new rows int l_maxRandom = 100; DataRowView l_firstNewDataRowView = m_addedRowsView.AddNew(); l_firstNewDataRowView["Name"] = "NewPerson" +         m_Random.Next(l_maxRandom).ToString(); l_firstNewDataRowView["Age"] = m_Random.Next(l_maxRandom); l_firstNewDataRowView.EndEdit(); DataRowView l_secondNewDataRowView = m_addedRowsView.AddNew(); l_secondNewDataRowView["Name"] = "NewPerson" +         m_Random.Next(l_maxRandom).ToString(); l_secondNewDataRowView["Age"] = m_Random.Next(l_maxRandom); l_secondNewDataRowView.EndEdit(); VB ' Delete two rows m_DataSet.Tables(0).Rows(0).Delete() m_DataSet.Tables(0).Rows(1).Delete() ' Add two new rows Dim l_maxRandom As Integer l_maxRandom = 100 Dim l_firstNewDataRowView As DataRowView l_firstNewDataRowView = m_addedRowsView.AddNew() l_firstNewDataRowView("Name") = "NewPerson" +         m_Random.Next(l_maxRandom).ToString() l_firstNewDataRowView("Age") = m_Random.Next(l_maxRandom) l_firstNewDataRowView.EndEdit() Dim l_secondNewDataRowView As DataRowView l_secondNewDataRowView = m_addedRowsView.AddNew() l_secondNewDataRowView("Name") = "NewPerson" +         m_Random.Next(l_maxRandom).ToString() l_secondNewDataRowView("Age") = m_Random.Next(l_maxRandom) l_secondNewDataRowView.EndEdit() 

Then the information is repainted, and now there are entries in all of the ListBoxes.

Clicking the button labeled Call AcceptChanges calls the AcceptChanges method and repaints the ListBox. The newly added rows now appear in the topmost ListBox because they are no longer considered "newly added" rows after AcceptChanges is called. There are no longer any newly added or deleted rows, so the bottom two ListBoxes are empty again.



Microsoft.NET Compact Framework Kick Start
Microsoft .NET Compact Framework Kick Start
ISBN: 0672325705
EAN: 2147483647
Year: 2003
Pages: 206

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net