This article is available at Code Project. Check it out to make comments, discuss or rate the article
I''''d like to thank Jean-Claude Manoli for developing his C# Code format, which i used in writing this tutorial.
Introduction
Questions regarding databinding, in one form or another, are probably the most asked in the aspnet newsgroups. Its clear everyone loves the idea of databinding but that more advanced functionality, such as event handling, conditional formatting and fine-tuning, aren''''t straightforward. The goal of this tutorial is shed light on some of the more common and frequently asked questions about the capabilities of databinding.
The Sample Program
Throughout this tutorial we''''ll use two separate data sources. The first will be your every-day dataset, the other will be a strongly-typed custom collection containing strongly-typed objects.
Our dataset will contain two tables, Customers and Orders: Customer StructureOrder Structure
Name
Type
Description
Name
Type
Description
CustomerId1
Int32
Unique customer identifier
OrderId
Int32
Unique order identifier
Name
String
Name of the customer
CustomerId1
Int32
Identifier of the custom who placed the order
Zip
String
Customer''''s primary ZIP or Portal code
Ordered
DateTime
Date the order was placed on
Enabled
Boolean
Whether the customer is currently active/enabled
Amount
Decimal
Dollar value of the order 1A DataRelation exists between the Customer.CustomerId and Order.CustomerId columns.
Our business entities will consist of an Owner and a Pet class: Owner StructurePets Structure
Name
Type
Description
Name
Type
Description
OwnerId
Int32
Unique owner identifier
PetId
Int32
Unique pet identifier
YearOfBirth
Int32
The year the owner was born in
Name
String
Name of the pet
FirstName
String
Owner''''s first name
IsNeutured
Boolean
Whether or not the pet is neutured
LastName
String
Owner''''s last name
Type
PetType
Indicates the type of pet (Dog, Cat, Fish, Bird, Rodent, Other)
Pets
PetCollection
Collection of pets the owner has
Understanding DataItem
You''''ve undoudbtedly made frequent use of the DataItem property, namely when using the DataBinding syntax to output a value:
It''''s important to understand that DataItem is actually an object, and that when you use the DataBinder.Eval function, it basically needs to figure out what type of object it is and how to get "customerId" from it. That''''s because your DataSource can be different things, such as a dataset or dataview, an arraylist or hashtable, a custom collection and more. Binding happens on a row-by-row basis and DataItem actually represents the current row being bound. For a DataSet, DataTable or DataView DataItem is actually an instance of DataRowView (you might think that the DataItem for a DataSet or DataTable would be an instance of DataRow, but when you bind either of these, the DefaultView is actually used, therefore DataItem will always be a DataRowView). When you are binding to a collection, DataItem is an instance of the item within the collection. We can observe this more clearly with the following code:
In the first repeater we are binding to a DataSet, the ItemTemplate shows how to access values by casting DataItem to a DataRowView [5,6], the AlternateItemTemplate will output the same information but through DataBinder.Eval [9,10].
In the second repeater we bind to a custom collection, again the ItemTemplate shows how to cast DataItem to the right type and access the fields directly [18,19] while the AlternateItemTemplate shows how the same is accomplished with DataBinder.Eval [22,23].
In both cases the ItemTemplate and AlternateItemTemplate will output the exact same information. The only difference is how the information is retrieved. DataBinder.Eval is far less performant, but has the benefit of being ignorant of the underlying structure, making it both quicker to develop and more likely to resist future changes. The goal here isn''''t to discuss the merits of these approaches, but simply show what DataItem truly is in order to build a proper foundation of understanding.
Formatting
Inline
While binding its possible to do simple formatting directly in the databinding expression or by calling functions which reside in codebehind.
The second repeater makes use of directly embedded expressions to toggle the visibility of certain controls [15,19]. The first repeater, which is bound to all Orders, makes use of two functions: FormatDate [4] and FormatMoney [5]. These methods could look something like:
While the above method is suitable for quick and simple problems, it lacks in elegance and capacity. Indeed, the 2nd example shows a serious lack of grace and dangerously blends presentation logic with UI. Avoiding burdening your presentation layer with any code is a practice worth eternal vigilence. To help accomplish this, the repeater, datalist and datagrid all expose a very powerful and useful event: OnItemDataBound.
OnItemDataBound fired for each row being bound to your datasource (in addition to when other templates are bound (header, footer, pager, ..)), it not only exposes the DataItem being used in binding, but also the complete template. OnItemDataBound starts to fire as soon as the DataBind() method is called on the repeater/datalist/datagrid.
Using OnItemDataBound lets us exercise fine control over exactly what happens during binding in a clean and robust framework. For example, reworking the 2nd repeater from above, we get: