Creating Dynamic Bound and Template columns in DataGrid by azamsharp

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.

Why create columns programmatically?

There are lot of situations where creating columns programmatically is more beneficial than creating using the design view. Suppose that you have a stored procedure that returns few columns from the database. You can only 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 than 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. Than we assigned the HeaderText and DataField property to the bound column and finally added the column to 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.

publicclass 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 templates 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.

publicvoid 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.

 

privatevoid 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 !