Published:
29 Jan 2008
|
Abstract
Sometimes we may be required to build GridView and DataList dynamically with different styles and with child controls in our project. This article will help you accomplish this task in ASP.NET 2.0 with the help of a case study. Satheesh first provides a brief overview of the scenario and then explores the step-by-step implementation of each module with supported source code. The steps include creation of a Template class, implementation of a dynamic DataList, using the Template class in DataList, implementation of a dynamic GridView, and the usage of Template class in GridView. The article is accompanied by the related Visual Studio project which enables you to instantly test drive the application. |
|
by Satheesh Babu
Feedback
|
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days):
67557/
60
|
|
|
Introduction |
Displaying tabular data to the users is one of the common
tasks we will perform in any site we build. In ASP.NET 1.x we make use of the
DataGrid, DataList and Repeater controls most of the time depending on the
need. With the introduction ASP.NET 2.0, we have GridView in the place of DataGrid
with some changes that make the control more easily usable than DataGrid with
the help of data source controls. Each time the need of displaying the data
will be different. Sometimes, we will require the data to be displayed to the
user where he/she should have edit/update/delete functionalities or we require
displaying the data with the header being displayed in the left as opposed to
top which makes us decide which of the above controls to use. Coming to our
subject, most of the time it is sufficient if we drag the control into the
WebForm instead of adding it dynamically to achieve the target. At times we
will require doing this dynamically which I took to discuss in this article
with both DataList and GridView control in ASP.NET 2.0.
Microsoft has designed both of the controls in such a way so
that the developer can use the flexibility and can build it dynamically by
giving dynamic styles and layouts to the data display. Moving forward I will
explain a scenario where we can have a dynamic DataList/GridView and construct
it.
|
Scenario |
Consider we are creating a site that hosts technical
articles similar to aspalliance.com/Codeproject.com with the authors submitting
their article on different categories. Consider an article index page that
displays the top 4 articles on each category from the author's submission. We
can have a separate tabular view for each category in the article index page.
Refer to the below "Figure 1 – Article Listing" for a clear
understanding.
It will be hard and time consuming if we manually add a GridView/DataList
for each new category added in the site. We can feel the difficulty if we add a
new GridView/DataList to the page manually whenever a new category is added to
the site and deploy it again. In this situation we can consider dynamically
adding a GridView/DataList to serve the need without any manual efforts
involved when a new category is added to the site. Therefore, we are preventing
editing the page frequently for every new category and deploying it, with only a
little overhead in development time as opposed to a static GridView/DataList.
Figure 1: Article Listing
There can be many other scenarios like, when we really do
not know how many resultset a stored procedure is going to return that has
dynamic queries depending upon some business rules. I will use the above
example of article site throughout this article to explain constructing dynamic
DataList/GridView.
How to achieve it?
It is achieved by implementing ITemplate interface in
System.Web.UI namespace.
In this article I will explain the construction of dynamic
DataList and GridView by building dynamic template columns. Moving forward I
will create dynamic template columns for both Datalist and gridview specifically
the resultset returned by the stored procedure. Template columns for both
datalist and gridview can be created by implementing the interface ITemplate in
System.Web.UI namespace. Refer to Listing 1 and class diagram in Figure 2 for
ITemplate interface.
Listing 1: ITemplate Interface
namespace System.Web.UI
{
// Summary:
// Defines the behavior for populating a templated ASP.NET server control with
// child controls. The child controls represent the inline templates defined
// on the page.
public interface ITemplate
{
// Summary:
// When implemented by a class, defines the System.Web.UI.Control
// object that
// child controls and templates belong to. These child controls
// are in turn
// defined within an inline template.
//
// Parameters:
// container:
// The System.Web.UI.Control object to contain the instances
// of controls from
// the inline template.
void InstantiateIn(Control container);
}
}
Figure 2: ITemplate class diagram
With this information we will now create header template,
item template and footer template column for these controls by implementing the
above ITemplate interface.
|
Steps for creating Template class |
1.
Create a Template class (MyTemplate class, Listing 2 –TemplateClass for
DataList) that implements ITemplate interface.
2.
Create a constructor for the class that takes ListItemType as argument
so that we can determine whether we are constructing HeaderTemplate, ItemTemplate
or FooterTemplate. Also, we can make it through by exposing ListItemType as
public property.
3.
Implement the InstantiateIn (Control container) method and construct the
corresponding template from the input gotten from the constructor. Refer to the
code (Listing 2 –TemplateClass for DataList and Listing 5 –TemplateClass for
GridView) for a clear understanding.
4.
For data binding and child control that require data binding, create a
data binding event to fill the data with the control. This event will be raised
after the template items are created with all its controls.
5.
The above 4 steps have been implemented in the code, Listing 2
–TemplateClass for DataList and
6.
Listing 5 –TemplateClass for GridView.
|
Implementing Dynamic DataList |
The DataList will have a Header template with Category Name
displayed. For example, if it is displaying ASP.NET article, the category name
will be ASP.NET. The articles will be displayed in the item template. For every
article in the item template we will display the title of the article as a
hyperlink that links to the original URL of the article with a description and
author name. The footer will show the number of articles present in this
category.
Listing 2: TemplateClass for DataList
public class MyTemplate : ITemplate
{
ListItemType _itemType;
private string _no;
private string _categoryName;
public string NoOfArticles
{
get
{
return _no;
}
set
{
_no = value;
}
}
public string CategoryName
{
get
{
return _categoryName;
}
set
{
_categoryName = value;
}
}
public MyTemplate(ListItemType Type)
{
_itemType = Type;
}
public void InstantiateIn(System.Web.UI.Control container)
{
Literal lc = new Literal();
switch (_itemType)
{
case ListItemType.Header:
lc.Text = "<div id=\"nifty\" class=\"PostCategory\"> "
+ CategoryName + "</div>";
break;
case ListItemType.Item:
lc.DataBinding += new EventHandler(TemplateControl_DataBinding);
break;
case ListItemType.Footer:
lc.Text = "<div style=\"text-align:right\">" + NoOfArticles
+ " Article(s) present in this category" + "</div>";
break;
}
container.Controls.Add(lc);
}
private void TemplateControl_DataBinding(object sender, System.EventArgs e)
{
Literal lc;
lc = (Literal)sender;
DataListItem container = (DataListItem)lc.NamingContainer;
lc.Text += "<div class=\"Post\"><div class=\"PostTitle\"><A href=" +
DataBinder.Eval(container.DataItem, "URL") + ">" +
DataBinder.Eval(container.DataItem, "Title") +
"</a></div><div class=\"PostSubtitle\">" +
DataBinder.Eval(container.DataItem, "Description") +
"</div> <div class=\"PostInfo\">Posted on " +
DataBinder.Eval(container.DataItem, "CreatedOn", "{0:d} @ {0:t}") + " By " +
DataBinder.Eval(container.DataItem, "CreatedBy") + " in " +
DataBinder.Eval(container.DataItem, "Category") + "</div> ";
}
}
In the above code I have used 2 public properties,
CategoryName and NoOfArticle, for displaying category name in Header Template
and for displaying a number of articles in Footer Template. We can also specify
this as constructor argument instead of giving it as public properties. I have
defined TemplateControl_DataBinding event to bind the data that is in
resultset.
|
Using the Template Class in DataList |
The following steps will take us through to use the above
created MyTemplate class to create header, item and footer templates
dynamically.
1.
Create a DataList object.
2.
Create an instance of our created dynamic template class by passing the
ListItemType corresponding to the type of the item.
3.
Assign the instance to the datalist template property like:
Listing 3: DataList Templates
DataListObject.HeaderTemplate = new MyTemplate(ListItemType.Header);
DataListObject.ItemTemplate = new MyTemplate(ListItemType.Item);
DataListObject.FooterTemplate = new MyTemplate(ListItemType.Footer);
The below code contains code that uses the MyTemplate class
to build the DataList dynamically. I have added a PlaceHolder in the WebForm
which will hold the dynamically created DataList after the execution.
Listing 4: Using TemplateClass
protected void Page_Load(object sender, EventArgs e)
{
for (int i = 0; i < dsArticles.Tables.Count; i++)
{
if (dsArticles.Tables[i].Rows.Count > 0)
{
DataList dlArt = ConstructDL(
dsArticles.Tables[i].Rows[0]["Category"].ToString(),
dsArticles.Tables[i].Rows.Count);
dlArt.DataSource = dsArticles.Tables[i];
dlArt.DataBind();
phArticles.Controls.Add(dlArt);
}
}
}
public DataList ConstructDL(string CategoryName,int Count)
{
DataList dlArt = new DataList();
MyTemplate headTemplate = new MyTemplate(ListItemType.Header);
headTemplate.CategoryName = CategoryName;
dlArt.HeaderTemplate = headTemplate;
dlArt.Width = Unit.Percentage(100);
dlArt.ItemTemplate = new MyTemplate(ListItemType.Item);
MyTemplate footerTemplate = new MyTemplate(ListItemType.Footer);
footerTemplate.NoOfArticles = Count.ToString();
dlArt.FooterTemplate = footerTemplate;
return dlArt;
}
In the above code, phArticles is the PlaceHolder id. Thus,
we have created the DataList dynamically and now we will move on to the
implementation of dynamic GridView.
|
Implementing Dynamic GridView |
Using the GridView to display the articles analogous to the
above with DataList will display the article in a slightly different layout.
Refer to the below figure.
Figure 3: Dynamic GridView
|
Constructing Dynamic GridView |
Displaying the articles in gridview will be different from
displaying in datalist. For achieving this, I have created two Template
classes,
·
DynamicGridViewTextTemplate
·
DynamicGridViewURLTemplate.
DynamicGridViewTextTemplate class is used to add a template
column with label while DynamicGridViewURLTemplate class is used to add the URL
of the article.
Listing 5: TemplateClass for GridView
public class DynamicGridViewTextTemplate : ITemplate
{
string _ColName;
DataControlRowType _rowType;
int _Count;
public DynamicGridViewTextTemplate(string ColName, DataControlRowType RowType)
{
_ColName = ColName;
_rowType = RowType;
}
public DynamicGridViewTextTemplate(DataControlRowType RowType,
int ArticleCount)
{
_rowType = RowType;
_Count = ArticleCount;
}
public void InstantiateIn(System.Web.UI.Control container)
{
switch (_rowType)
{
case DataControlRowType.Header:
Literal lc = new Literal();
lc.Text = "<b>" + _ColName + "</b>";
container.Controls.Add(lc);
break;
case DataControlRowType.DataRow:
Label lbl = new Label();
lbl.DataBinding += new EventHandler(this.lbl_DataBind);
container.Controls.Add(lbl);
break;
case DataControlRowType.Footer:
Literal flc = new Literal();
flc.Text = "<b>Total No of Articles:" + _Count + "</b>";
container.Controls.Add(flc);
break;
default:
break;
}
}
private void lbl_DataBind(Object sender, EventArgs e)
{
Label lbl = (Label)sender;
GridViewRow row = (GridViewRow)lbl.NamingContainer;
lbl.Text =DataBinder.Eval(row.DataItem, _ColName).ToString();
}
}
public class DynamicGridViewURLTemplate : ITemplate
{
string _ColNameText;
string _ColNameURL;
DataControlRowType _rowType;
public DynamicGridViewURLTemplate(string ColNameText,
string ColNameURL, DataControlRowType RowType)
{
_ColNameText = ColNameText;
_rowType = RowType;
_ColNameURL = ColNameURL;
}
public void InstantiateIn(System.Web.UI.Control container)
{
switch (_rowType)
{
case DataControlRowType.Header:
Literal lc = new Literal();
lc.Text = "<b>" + _ColNameURL + "</b>";
container.Controls.Add(lc);
break;
case DataControlRowType.DataRow:
HyperLink hpl = new HyperLink();
hpl.Target = "_blank";
hpl.DataBinding += new EventHandler(this.hpl_DataBind);
container.Controls.Add(hpl);
break;
default:
break;
}
}
private void hpl_DataBind(Object sender, EventArgs e)
{
HyperLink hpl = (HyperLink)sender;
GridViewRow row = (GridViewRow)hpl.NamingContainer;
hpl.NavigateUrl = DataBinder.Eval(row.DataItem, _ColNameURL).ToString();
hpl.Text = "<div class=\"Post\"><div class=\"PostTitle\">" +
DataBinder.Eval(row.DataItem, _ColNameText).ToString() + "</div></div>";
}
}
|
Using the Template Class in GridView |
Using dynamic template in GridView is slightly different
from DataList. We will create the dynamic GridView in column wise with header
template, item template and footer template from the first column to the last.
Steps
1.
Create a GridView Object.
2.
Create an instance of TemplateField object.
3.
Instantiate the Dynamic template class with proper ListItemType and
assign it to the corresponding template property of TemplateField object and
finally add this object to the column collection of GridView.
Listing 6: Templates of GridView
TemplateField tf = new TemplateField();
tf.HeaderTemplate = new DynamicGridViewTextTemplate("ArticleID",
DataControlRowType.Header);
tf.ItemTemplate = new DynamicGridViewTextTemplate("ArticleID",
DataControlRowType.DataRow);
tf.FooterTemplate = new DynamicGridViewTextTemplate(DataControlRowType.Footer,
ds.Tables[i].Rows.Count);
If you compare the implementation of DataList, in Gridview
we will not create a dynamic template for the grid, instead we create it for
the grid’s column (TemplateField).
Listing 7: Using Template class
for (int i = 0; i < ds.Tables.Count; i++)
{
if (ds.Tables[i].Rows.Count > 0)
{
GridView gvDynamicArticle = new GridView();
gvDynamicArticle.Width = Unit.Pixel(700);
gvDynamicArticle.BorderWidth = Unit.Pixel(0);
gvDynamicArticle.Caption =
"<div id=\"nifty\" class=\"PostCategory\">" +
ds.Tables[i].Rows[0]["Category"].ToString() +
" Articles</div>";
gvDynamicArticle.AutoGenerateColumns = false;
gvDynamicArticle.ShowFooter = true;
TemplateField tf = null;
tf = new TemplateField();
tf.HeaderTemplate = new DynamicGridViewTextTemplate("ArticleID",
DataControlRowType.Header);
tf.ItemTemplate = new DynamicGridViewTextTemplate("ArticleID",
DataControlRowType.DataRow);
tf.FooterTemplate = new DynamicGridViewTextTemplate(
DataControlRowType.Footer, ds.Tables[i].Rows.Count);
gvDynamicArticle.Columns.Add(tf);
tf = new TemplateField();
tf.HeaderTemplate = new DynamicGridViewTextTemplate("Title",
DataControlRowType.Header);
tf.ItemTemplate = new DynamicGridViewTextTemplate("Title",
DataControlRowType.DataRow);
gvDynamicArticle.Columns.Add(tf);
tf = new TemplateField();
tf.HeaderTemplate = new DynamicGridViewTextTemplate("Description",
DataControlRowType.Header);
tf.ItemTemplate = new DynamicGridViewTextTemplate("Description",
DataControlRowType.DataRow);
gvDynamicArticle.Columns.Add(tf);
tf = new TemplateField();
tf.HeaderTemplate = new DynamicGridViewURLTemplate("Title", "URL",
DataControlRowType.Header);
tf.ItemTemplate = new DynamicGridViewURLTemplate("Title", "URL",
DataControlRowType.DataRow);
gvDynamicArticle.Columns.Add(tf);
tf = new TemplateField();
tf.HeaderTemplate = new DynamicGridViewTextTemplate("Author",
DataControlRowType.Header);
tf.ItemTemplate = new DynamicGridViewTextTemplate("CreatedBy",
DataControlRowType.DataRow);
gvDynamicArticle.Columns.Add(tf);
gvDynamicArticle.RowDataBound += new
GridViewRowEventHandler(this.DynamicGrid_RowDataBound);
gvDynamicArticle.DataSource = ds.Tables[i];
gvDynamicArticle.DataBind();
phDynamicGridHolder.Controls.Add(gvDynamicArticle);
}
}
In the above code (Listing 6 –Using Template class) we can
clearly understand that we are creating the dynamic template for the GridView's
column as opposed to DataList where we created the template for the grid
itself. To throw more light on this it means that we are creating the first
column’s header, item and footer and adding it to the GridView's column list
through TemplateField object to the last column as I said earlier.
|
Downloads |
|
Conclusion |
The functionalities like displaying table of data on a
public website like the one in our example or displaying report in a web page
in an enterprise application is one the major things that we do in everyday
development. This article will help you to do that dynamically with the help of
DataList and GridView in ASP.NET 2.0. Enjoy Coding!!!
|
|
|
User Comments
Title:
aaaa
Name:
aaaa
Date:
2012-10-19 12:48:33 AM
Comment:
aaaaa
|
Title:
6u5u75
Name:
657657
Date:
2012-10-19 12:48:18 AM
Comment:
hgfgfhfgh
|
Title:
sgrryry
Name:
ryryytr
Date:
2012-08-18 9:00:37 AM
Comment:
hkhafsjkfbudssdjfwuifwfbweufwefwefbewjfuwiefw
|
Title:
2012 NFL jerseys
Name:
NIKE NFL jerseys
Date:
2012-05-20 11:33:16 PM
Comment:
[/pre]Cheap NFL,NBA,MLB,NHL [url=http://www.jersey2shop.com/]Jerseys From China[/url] [url=http://www.jersey2shop.com/]2012 nike nfl Jerseys[/url] [url=http://www.jersey2shop.com/]cheap China Jerseys[/url] [url=http://www.jersey2shop.com/]Sports Jerseys China[/url] [url=http://www.jersey2shop.com/NFL-Jerseys-c68/]NFL Jerseys China[/url] [url=http://www.jersey2shop.com/NBA-Jerseys-c77/]NBA Jerseys China[/url] NHL Jerseys China [url=http://www.jersey2shop.com/MLB-Jerseys-c94/]MLB Jerseys China[/url]NFL jerseys For Sale online.All Our Jerseys Are Sewn On and Directly From Chinese Jerseys Factory [/pre] [pre]We Are Professional China jerseys Wholesaler [url=http://www.cheapjersey2store.com/]Wholesale cheap jerseys[/url]Cheap mlb jerseys [url= http://www.cheapjersey2store.com/]2012 mlb all atar jerseys[/url] [url= http://www.cheapjersey2store.com/ [/url]Cheap China Wholesael[/url] [url= http://www.cheapjersey2store.com/]Wholesale jerseys From China[/url] [url=http://www.cheapjersey2store.com/]2012 nike nfl Jerseys[/url]Free Shipping,Cheap Price,7 Days Deliver [/pre] [/pre] We are professional jerseys manufacturer from china,wholesal sports [url= http://www.cheapjersey2store.com/]Jerseys From China[/url] [url=http://www.cheapjersey2store.com/NFL-Jerseys-c68]NFL jerseys China[/url] [url=http://www.cheapjersey2store.com/NHL-Jerseys-c96/]NHL Jerseys China[/url] [url=http://www.cheapjersey2store.com/NBA-Jerseys-c77/]NBA Jerseys China[/url] [url=http://www.cheapjersey2store.com/MLB-Jerseys-c94/]MLB Jerseys China[/url] [url= http://www.cheapjersey2store.com/]China Jerseys[/url],Free Shipping [/pre] [/pre] We are professional jerseys manufacturer from china,wholesal sports [url= http://www.jerseycaptain.com/]cheap jerseys sale online [/url] [url= http://www.jerseycaptain.com/]2012 nike nfl Jerseys[/url] [url=http://www.jerseycaptain.com/NFL-Jerseys-c68]cheap NFL jerseys China[/url] [url=http://www.jerseycaptain.com/NHL-Jerseys-c96/]NHL Jerseys C
|
Title:
good article
Name:
Mahmoud ALGoul
Date:
2011-02-02 5:51:30 AM
Comment:
cool article, but how I can add paging for the code, any help please.
|
Title:
FANTASTIC!!
Name:
André
Date:
2010-03-12 5:02:57 PM
Comment:
Thank You!! Great job and easy to understand..
|
Title:
web filtering policy
Name:
adel
Date:
2009-07-29 5:47:19 AM
Comment:
i need to design web filtering policy
|
Title:
Itemplate funtion not working
Name:
Prabhat Sinha
Date:
2009-06-25 7:17:46 AM
Comment:
its really good work in C# but itemplete funtion not working in vb.net please help me
|
Title:
If items dissapear in postback
Name:
TiagoReil
Date:
2009-06-16 1:23:08 PM
Comment:
I had to do something like this, and had lots of problems. First of all, when you do a postback, you loose all the dinamic templates. Not databounts added dinamically, but only the ones that are templates disapear always. So I run the code on every postback. But then the events in the grid, that are loaded dinamically, started acting strange. Runing events that had already run, etc.
The solution and correct way to do this is to add all the code for adding columns on the PreInit event. Thats the correct place to add the creation of the columns.
Santiago.
|
Title:
Great example
Name:
Vijay
Date:
2009-06-06 3:36:28 AM
Comment:
What is DynamicGrid_RowDataBound doing?
|
Title:
Working example
Name:
Mindaugas
Date:
2009-06-03 5:05:06 AM
Comment:
Working example. Thank you!
|
Title:
Dynamic GridView
Name:
Shaju M.K
Date:
2009-02-12 5:38:02 PM
Comment:
Hi Satheesh Babu, Really its a very nice article that helped me to solve the issue that I faced in the development stage.
Thank You Very much!
|
Title:
JSON LINQ
Name:
willian brasil
Date:
2008-10-03 1:18:03 PM
Comment:
Very Good!
|
Title:
Data List
Name:
Deleep Kumar Pavana
Date:
2008-09-11 5:03:07 AM
Comment:
Hi satheesh, Its good but repeat colomns property is not working properly on that,if i use table tag to display data in table format..
|
Title:
Good Work ....
Name:
Mudassar C
Date:
2008-07-17 1:09:10 AM
Comment:
Hi Sateesh, Its a really good article to read.. Good piece of Code..
Mudassar Chandle
|
Title:
Data List And GridView
Name:
Santosh Kumar
Date:
2008-06-24 3:36:54 AM
Comment:
Hi Satheesh, I read this article , good work done. Santosh Kumar http://www.operativesystems.com
|
Title:
VB Please
Name:
Matt
Date:
2008-06-03 1:11:24 AM
Comment:
Any chance I can get this in VB? Please THanks Matt
|
Title:
problem with binding
Name:
Kannan
Date:
2008-05-15 2:51:40 AM
Comment:
All item template values displayed at once.no reapeated datalist display
|
Title:
muhajiran bugok
Name:
muhajiran bugok
Date:
2008-05-09 6:43:36 AM
Comment:
this is very helpful.. -putang ina nyo lahat
|
Title:
sivaram
Name:
sivaram
Date:
2008-02-04 1:47:59 AM
Comment:
Thanks.
hi i read your article.it is well and good article.
|
|
Product Spotlight
|
|