Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Dynamic columns addition to GridView

4.40/5 (3 votes)
17 May 2013CPOL2 min read 32K   2  
How to add columns dynamically in GridView......

Introduction

After joining Code Project, my first aim was to post an article. But I was confused What? and Why?

When I started my career as a developer I was very much afraid of GRIDVIEW. I did lots of R&D on this particular topic and found GridView as a very powerful tool provided by MS.

But particularly the dynamic addition of Itemtemplate was a nightmare for me.

In this topic I will throw some light on the same 

Using the code

Add GridView control under form tags. 

Client Side: 

ASP.NET
<%@ Page Language="C#" AutoEventWireup="true" 
  CodeBehind="MyPage.aspx.cs" Inherits="DynamicGridViewTest.MyPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="gvSample" 
          AutoGenerateColumns="false" runat="server">
 
    </asp:GridView>
    </div>
    </form>
</body>
</html>  
 

GridView has been added and now question arises how we are going to add TemplateFields to the GridView.

For this we will add a class which will extend ITemplate interface.

Here I have added class named CreateItemTemplate.

In this class three private properties has been defined:

  1. ListItemType _myListItemType : This will check the type of list item we want to add to the TemplateField i.e Header,Item,Footer .etc as per our will.
  2. Type _cntrlType : This will be used to set the type of UI control we want to add in the Item of the Template field.
  3. string _columnName : This has been used for setting the header name or the column name with which the control of the Item will get bound.

Constructor has been overloaded to set the properties.

C#
public CreateItemTemplate(){}

public CreateItemTemplate(ListItemType listItemType, Type cntrlType, string strColumnName)
{
    _myListItemType = listItemType;
    _cntrlType = cntrlType;
    _columnName = strColumnName;
}

Now override the function InstantiateIn of the interface ITemplate.

In this function all the UI controls are added to the Cell(Header,Item,Footer,etc) and data is bound from the collection.  This function will execute when the GridView is bound using any source. 

C#
public void InstantiateIn(Control container)
{
    switch (_myListItemType)
    {
        case ListItemType.Header:
            //Add controls in the Header cell.
            Label lblHeader = new Label();
            lblHeader.Text = _columnName;
            container.Controls.Add(lblHeader);
            break;

        case ListItemType.Item:
            //Add controls in the Item cell.
            if (_cntrlType == typeof(Label))
            {
                Label lblItem = new Label(); 
                //Add Event for binding data to control.
                lblItem.DataBinding += new EventHandler(BindDataToGrid);
                container.Controls.Add(lblItem);
            }
            else if (_cntrlType == typeof(TextBox))
            {
                //Code can be added here for adding TextBox
            }
           

            break;

        case ListItemType.Footer:
           //Add controls in the Footer cell.
            break;
    }
}

protected void BindDataToGrid(object sender, EventArgs e)
{
    if(sender is Label)
    {
        Label lbl = (Label)sender;
        GridViewRow container1 = (GridViewRow)lbl.NamingContainer;
        object dataValue = DataBinder.Eval(container1.DataItem, _columnName);
        if (dataValue != null)
        {
            lbl.Text = dataValue.ToString();
        }
    }
}

The event BindDataToGrid binds the data of collection with mentioned column name to the control.

Now lets proceed and learn how to add Itemtemplate using the class CreateItemTemplate .

Code Behind: 

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;

namespace DynamicGridViewTest
{
    public partial class MyPage : System.Web.UI.Page
    {
        

        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                BindGrid();
            }
            catch (Exception)
            {
                //TODO
            }
        }

        private void BindGrid()
        {
            //Local DataTable for binding with the GriedView
            DataTable dtTemp = new DataTable();
            dtTemp.Columns.Add("Cities", typeof(string));//Columns added
            dtTemp.Columns.Add("State", typeof(string));
            dtTemp.Rows.Add("Mumbai,Pune,Nasik", "Maharashtra");
            dtTemp.Rows.Add("Amritsar,Jalandhar", "Punjab");

            //Add TemplateField for every columns of datatable.
            foreach (DataColumn dtCol in dtTemp.Columns)
            {
                AddTemplateField(dtCol.ColumnName);
            }           
            
            
            gvSample.DataSource = dtTemp;
            gvSample.DataBind();
        }

        private void AddTemplateField(string strHeaderText)
        {
            TemplateField objTemplateField = new TemplateField();
            //Add Header Cell
            objTemplateField.HeaderTemplate = 
              new CreateItemTemplate(ListItemType.Header, typeof(Label), strHeaderText);
            objTemplateField.HeaderStyle.Width = Unit.Percentage(30);   
            //Add Item Cell
            objTemplateField.ItemTemplate = 
              new CreateItemTemplate(ListItemType.Item, typeof(Label), strHeaderText);
            gvSample.Columns.Add(objTemplateField);
        }
    }
}

Function AddTemplateField  is called for every column of data table and Itemtemplates are added.

Note:

As the ViewState of TemplateFields are not maintained, for every postback the TemplateFields should be recreated or you will not be able to view the Columns. 

So choose wisely where want to use this method of binding GridView and Program well.  

License

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