Introduction:
We are all familiar with Datagrid control's bound and template column. Usually we build columns using property builder. In this article I will show that how you can programmatically create bound and template columns of datagrid control.
Why create columns programmatically?
There are lot of situations where creating columns programmatically is more beneficial than creating them using the design view. Suppose that you have a stored procedure that returns several columns from the database. You can use the design view of datagrid to add columns if you know that how many columns are being returned. If you don't know the number of columns returned then creating the columns at runtime will be a better approach.
Creating Bound Columns Dynamically:
Let's see how we can easily create and bind the Bound Columns to the datagrid. We simply create an instance of the BoundColumn class. Then we assigned the HeaderText and DataField property to the bound column and finally we add the columns the Datagrid.
|
// Create Bound Columns
BoundColumn nameColumn =
new
BoundColumn();
nameColumn.HeaderText = "Name";
nameColumn.DataField = "UserName";
myDataGrid.Columns.Add(nameColumn);
myDataGrid.DataSource = ds;
myDataGrid.DataBind();
|
Creating Template Columns Dynamically:
Creating Template columns dynamically is not as easy as Bound columns. Let's see the code below:
|
for
(
int
i=1 ; i <= dt.Columns.Count -1 ; i++)
{
// Creating Template Column
TemplateColumn test =
new
TemplateColumn();
string
columnName = dt.Columns[i].ColumnName;
test.HeaderTemplate =
new
DataGridTemplate(ListItemType.Header,columnName);
// Adding the Rows to the DataGrid
for
(
int
j=0; j<= dt.Rows.Count - 1 ; j++)
{
string
score = dt.Rows[j][i].ToString();
test.ItemTemplate =
new
DataGridTemplate(ListItemType.Item,score);
}
myDataGrid.Columns.Add(test);
}
|
We are running a loop which goes through every item in a DataTable object. Inside the loop we create an instance of the Template column and assign the column name from the datatable to template column header template. Then we have an inner loop which fills the rows from the datatable to the template column items.
You might be wondering that what is "DataGridTemplate". Its a class that is used to generate the column type of the template columns. Let's see small code snippet from that class.
|
public
class
DataGridTemplate : System.Web.UI.Page,ITemplate
{
ListItemType templateType;
string
columnName;
public
DataGridTemplate(ListItemType type,
string
colname)
{
templateType = type;
columnName = colname;
}
|
The class inherits the "ITemplate" interface which is the same interface that all the datagrid template column uses. "ListItemType" denotes the type of the template that we wish to use.
All the columns are added to the control hierarchy in the InstantiateIn() method. This method is called when ever we bind the grid using the DataBind method.
|
public
void
InstantiateIn(System.Web.UI.Control container)
{
Literal lc =
new
Literal();
LinkButton lb =
new
LinkButton();
switch
(templateType)
{
case
ListItemType.Header:
lc.Text = "<B>" + columnName + "</B>";
lb.Text = "Edit";
lb.CommandName = "EditButton";
container.Controls.Add(lb);
container.Controls.Add(lc);
break
;
case
ListItemType.Item:
lc.Text = "Item " + columnName;
container.Controls.Add(lc);
break
;
case
ListItemType.EditItem:
TextBox tb =
new
TextBox();
tb.Text = "";
container.Controls.Add(tb);
break
;
case
ListItemType.Footer:
lc.Text = "<I>" + columnName + "</I>";
container.Controls.Add(lc);
break
;
}
|
As you can see this class contains different types of ListItemTypes, which is an enumerated type. ListItemType denotes that what action to take for what template. I have made all the ListItemTypes "bold" so you can easily identify them. As you can see if you use editItemTemplate you will get the TextBoxes and for other templates you will get Literal controls.
Where to put the column building code?
It is very important that you place your Datagrid building code in the right place or else it won't work as expected. Here is a bad example of creating a datagrid which is made of dynamic columns.
|
if
(!Page.IsPostBack)
{
BuildDataGrid();
}
|
There is no doubt that if you implemented the BuildDataGrid method without any mistakes than it will show you datagrid on Page Load event. But as soon as the postback happens your grid will be gone. That's why its not the perfect place for the "BuildDataGrid" method.
You should place the BuildDataGrid method in the InitializeComponent method which is called at the very early stages of the Page life cycle.
|
private
void
InitializeComponent()
{
this
.myDataGrid.ItemCommand +=
new
System.Web.UI.WebControls.DataGridCommandEventHandler(
this
.myDataGrid_ItemCommand);
this
.Load +=
new
System.EventHandler(
this
.Page_Load);
// Make the Datagrid
BuildDataGrid();
}
|
This will ensure that each time the page is created all the controls are created as well.
Conclusion:
Building columns dynamically might be little challenging but it gives you great flexibility to model your columns in any way you like. I hope you liked the article, happy coding !