Click here to Skip to main content
Click here to Skip to main content
Go to top

TableDataSource - Binding DataTable to Rich Data Controls

, 20 Jun 2007
Rate this:
Please Sign up or sign in to vote.
Binding DataTable to Rich Data Controls

Introduction

The current version 2.0 of the ASP.NET Framework has several rich data controls like GridView. It works optimally when bound using the DataSourceID parameter. The rich controls work well if directly connected to SQL database using SqlDataSource object. Similar services should provide the binding tool ObjectDataSource for binding to data in memory, for business objects.

The author tried binding using the ObjectDataSource tool. The main parameter of the tool defines only type of bound object - its temporary instance is created either only during the binding operation, or the operations are provided by static functions of the type without creating an object at all. The author met with significant problems in realization of interaction between those temporary objects and/or static functions and other objects on the Web page, particularly when the final data source is some generic collection like generic List<...>; better results give binding of classical DataTable. Notwithstanding that, rich functionality of the DataTable provides for changed rows of both old and modified data.

Background

Instead of creating a particular data structure and converting some collection of business objects into a generic collection, it can be transformed to classical .NET data structure DataTable. When bound to rich controls, DataTable ensures their maximal functionality without writing complicated user code. The result of such reflection was the idea of a simple data binding element between the rich control and the table; the user would update data through the controls and the program would finally transform changes stored in DataTable to real data objects. Naturally, it would be optimal, if business data would be stored directly in DataTables or its collection - DataSet, possibly including their relations - or structures, where data conversion is simple.

The author's conception of the use of the described control is in filling the data table, its update by the user, and finally resolution (using corresponding buttons) to COMMIT data changes (i.e. save changes in business objects and calling DataTable.AcceptChanges()) or ignore them (calling DataTable.RejectChanges()). Or more generally: custom data source control or simply *.aspx page can initially transfer data from a business object collection to the table, then perform its update using rich data control, and finally either transfer data back to the business object collection (e.g. selecting button COMMIT or APPLY), or rollback all changes (e.g. selecting button IGNORE).

The entire project was based on an example from the MSDN library - class CsvDataSource and Web presentation (and user comments) of Nikhil Kothari referred to below.

Naturally, realization of such ideas often result in more complicated software than was originally seen. The presented project illustrates two approaches:

  1. Editing data directly in one GridView control bound using TableDataSource editing its columns directly (TestTableDataSource.aspx).

  2. Selecting data rows in GridView and their editing in DetailsView control using two TableDataSources binding a single table to two controls (TestTableMasterDetail.aspx).

The presented example is based on our specific conditions, where each table has one integer identity column as key; it can be simply adapted for a more general case. It is based on simple logic, which can be well understood; the author is not a specialist in the field. Reasonable comments and improvements are welcome.

The example project is started using the solution WEB.sln. It consists of two projects: control library project creating library TableDataSource.dll and own Web site (two pages) in folder WEB.

Basic Components

The presented example consists of these basic components:

  • Class TableDataSource based on system class System.Web.UI.DataSourceControl realizing basic functionality
  • Complementary class TableDataSourceView based on the complementary base class System.Web.UI.DataSourceView realizing own data binding returned from TableDataSource to bound control
  • Two Web pages TestTableDataSource.aspx and TestTableMasterDetail.aspx realizing updating of data in the bound table both directly in GridView and master-detail schema of related GridView and DetailsView. Both DataGrids naturally enable paging and column sorting, which require practically no additional code.
  • Auxiliary enum type Gender illustrating use of user defined classes and template columns in rich controls
  • Auxiliary generic static function BindEnum<T>() for binding of DropDownLists to enum data types. Helper class Util helps to bypass limitations of the C# language.

The last two components are presented as part of the source file TableDataSource.cs which also contain the source of the two basic classes of user component TableDataSource.

Class TableDataSource

This class declares these basic elements:

  • Default constructor
  • Property Table of type DataTable is generally set from the external program and stores reference to DataTable object. When setting this property, objects bind to events with corresponding changes in Table object.
  • Property RowFilter of type string. This string represents constant part of row selection filter, while the variable part is determined by the next parameter. While setting the property assigns only its constant part, upon get it returns full WHILE query condition.
  • Parameter collection <SelectParameters> of individual parameters; each parameter defines one condition in the form ident = value; all conditions including possible RowFilter are connected by logical operator AND . Parameter collection can be edited using property window by standard parameter collection editor.
  • Method DataSourceView GetView(string viewName) realizes own data binding returning instance of the class DataSourceView to bound rich data control.
  • Internal int property InsertedKey is helper to set temporary unique negative keys for inserted columns; final value is set later during final insertion.
  • Private event handler tableDataChanged(object source, EventArgs e) transferring table change events to base class by calling its function RaiseDataSourceChangedEvent(e).

Class TableDataSourceView

This class is used internally from the base class and declares these basic elements:

  • Constructor public TableDataSourceView(IDataSource owner, string name) analogous to the base class. Owner is the corresponding TableDataSource object, name is derived from its ID and is used mainly for debugging.
  • Binding requires property public static string DefaultViewName = "TableSourceView".
  • Overridden virtual function System.Collections.IEnumerable ExecuteSelect(DataSourceSelectArguments arguments) realizes own data transfer to rich control. Returns DataView derived from bound table with supplied sort expression from arguments and RowFilter derived from properties of view owner.
  • Overridden virtual function ExecuteUpdate(System.Collections.IDictionary keys, System.Collections.IDictionary values, System.Collections.IDictionary oldValues) realizing update of one data row.
  • Overridden virtual function ExecuteDelete(System.Collections.IDictionary keys, System.Collections.IDictionary oldValues) realizing deleting of one data row.
  • Overridden virtual function ExecuteInsert(System.Collections.IDictionary values) realizing insertion of one data row.

Conclusion

Presented data control is only a primitive realization of concept being much better realized in standard .NET data source controls. It demonstrates basic principles, while details can be supplemented according to first experiences.

The author appreciates any reader comments and advice for improving the presented material.

Correction

  1. After finishing, I found some improvements enabling automatic rebind after change of RowFilter - it is tested in OnPreRender and then control notifies bound elements.
  2. I thank Ebrahimhassan for his valuable discussion. I found some bugs caused by incorrect management of null and DBNull values - I believe that now it works better.
  3. The functionality of the presented example is limited to conditions and rules applied in my environment: All tables have unique primary keys with single numeric values - more general case is left to readers. The main reason of my example is presenting principles, not final solutions.
  4. New version lets in the Master - Detail model inserted row open for editing - it illustrates a new generation of PageIndex and SelectedIndex in the bound grid.
  5. Open source control has one significant advantage - its user can set breakpoints to its key points (e.g. ExecuteSelect, ExecuteUpdate ... in the presented example) and study behavior of developed code. It can be used as a valuable debugging tool.

History

  • 11th March, 2007 - Initial version
  • 13th March, 2007 - Corrected, completed, new references
  • 20th June, 2007 - Revised, bug removal

References

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

brtnik
Publisher
Czech Republic Czech Republic
I'm 63 years old, originally physicist, later programmer by profession, now pensioner.
 
Jirí Šoler

Comments and Discussions

 
QuestionWould ObjectDataSource still work? PinmemberMike Ellison13-Mar-07 7:34 
AnswerRe: Would ObjectDataSource still work? Pinmemberbrtnik14-Mar-07 22:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 20 Jun 2007
Article Copyright 2007 by brtnik
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid