<body><script type="text/javascript"> function setAttributeOnload(object, attribute, val) { if(window.addEventListener) { window.addEventListener('load', function(){ object[attribute] = val; }, false); } else { window.attachEvent('onload', function(){ object[attribute] = val; }); } } </script> <div id="navbar-iframe-container"></div> <script type="text/javascript" src="https://apis.google.com/js/platform.js"></script> <script type="text/javascript"> gapi.load("gapi.iframes:gapi.iframes.style.bubble", function() { if (gapi.iframes && gapi.iframes.getContext) { gapi.iframes.getContext().openChild({ url: 'https://www.blogger.com/navbar/19834389?origin\x3dhttp://netchallenges.blogspot.com', where: document.getElementById("navbar-iframe-container"), id: "navbar-iframe" }); } }); </script>

Put some text here ...

Put some text here ...

Put some text here ...

Put some text here ...

Put some text here ...

Put some text here ...

Name:
Location: Bright, Underground, United States

Grandeur isnt my style; Excellence is!

Powered by Blogger

Tuesday, December 13, 2005

ReUsing DataTable with DataGrid


Language: VB.NET Version 1.11
Task:Create a tool like SQL-Query analyzer that returns result in a grid.
Problem: The data grid does not always display data!
ds.tables("searchResults").clear()
'Custom function that uses a SQLDataAdapter to fill the datatable with results of the query
fillBrowseSet(Me.query.Text.Trim, searchDT)
datagrid1.datasource = ds.tables("searchResults")
This works fine the first time. DataTable is filled and datagrid1 displays the result. The following request display a blank grid with no data, but correct column


Solution 1
Replace, ds.tables("searchResults").clear() with
ds.tables("searchResults").reset()
Then, bind the datagrid with the DataTable.

Problem with solution 1: If underlying schema of the datatable keeps changing, the data may appear, but all column may not appear correctly. This is usually due to the underlying contraint collection and the primary key collection bindings.

Explaination:
datagrid1.datasource = ds.tables("searchResults") AND datagrid1.datasource = ds.tables("searchResults").DefaulView

Both are effectively the same statements. datagrid1.datasource = ds.tables("searchResults") implicitly uses the dataview generated for the datatable, and datagrid1.datasource = ds.tables("searchResults").DefaulView explicitly points to the dataview to bind. The point is, DataSource property of the datagrid uses a DataView object to establish mapping on the datagrid column(s) with columns and data stored in the DataTable object.

The DefaultView property of the DataTable is a ReadOnly property that points to an immutable object. Every DataTable object has exactly one DataView object created for it. This DataView object is created during the construction of the DataTable object. This DataView object is therefore based on the underlying schema of the DataTable object at that time. The problem is, when the underlying schema of the DataTable changes, the associated DataView object is not automatically notified of the change, and is not re-Synchronized. So, the result is a disconnected DataView that is unable to provide a current binding to the DataGrid object.

You can test these findings using the debugger and checking the
TableName and Count properties of both the DataView and DataTable. You will notice, the two will contain the same values initially. The defaul DataView object will be reset upon disconnect and display a Count of 0 (zero).


My Solution
'Eliminate the use of a large and bulky DataSet object.
Private searchDT As DataTable
Private searchView As New DataView

searchDT = New DataTable("searchResult")
searchView.AllowDelete = False
searchView.AllowEdit = False
searchView.AllowNew = False

searchDT.Reset()
'The DataView object being used is no longer immutable, and can be manipulated
If Not searchView.Table Is Nothing Then
searchView.Table = Nothing
End If
fillBrowseSet(Me.query.Text.Trim, searchDT, False)
'Attach the dataview to refreshed DataTable object.
'This refreshes the DataVie
w
searchView.Table = searchDT
Me.resultGrid.SetDataBinding(searchView, "")

Advantages to this Technique:
1) We do not find the need to create a new DataView object for every new schema of DataTable
2) We avoid the use of a bulky DataSet object, and minimize cost associate with processing and boxing/un-boxing DataSet object. An independant DataTable object is enough for our purposes
3) We have control of the DataView object contained by the DataTable. searchView.Table = searchDT sets the new dataview object accessible by DefaultView property of DataTable

Comments on "ReUsing DataTable with DataGrid"

 

post a comment