Click here to Skip to main content
15,911,646 members
Articles / Web Development / ASP.NET
Article

How to create template columns dynamically in a grid view

Rate me:
Please Sign up or sign in to vote.
4.32/5 (42 votes)
17 Mar 2006Ms-PL5 min read 557.4K   8.2K   81   65
This article describes about how to create template columns dynamically in a grid view.

Sample Image - DynamicColumnsWithTemplate.jpg

Introduction

This article describes about how to create template columns dynamically in a grid view.

Many times we have the requirement where we have to create columns dynamically. This article describes you about the dynamic loading of data using the DataTable as the datasource.

 

Let’s have a look at the code to understand better.

 <o:p>

Create a gridview in the page,

  1. Drag and drop the GridView on to the page

Or

  1. Manually type GridView definition in the page.

 <o:p>

<table border="0" cellpadding="0" cellspacing="0"><o:p>

            <tr><o:p>

                <td><o:p>

                    <strong>Dynamic Grid with Template Column</strong></td><o:p>

            </tr><o:p>

            <tr><o:p>

                <td><o:p>

                    <asp:GridView ID="GrdDynamic" runat="server" AutoGenerateColumns="False"><o:p>

                    <Columns><o:p>

                    </Columns><o:p>

                    </asp:GridView><o:p>

                </td><o:p>

            </tr><o:p>

        </table>

 <o:p>

With this we are done with creating a GridView in the page.

Let’s move on to the code-beside to understand the background history of the page.

Here I am describing about, how to create template columns.

 <o:p>

//Iterate through the columns of the datatable to set the data bound field dynamically.<o:p>

        foreach (DataColumn col in dt.Columns)<o:p>

        {<o:p>

            //Declare the bound field and allocate memory for the bound field.<o:p>

            TemplateField bfield = new TemplateField();<o:p>

 <o:p>

            //Initalize the DataField value.<o:p>

            bfield.HeaderTemplate = new GridViewTemplate(ListItemType.Header, col.ColumnName);<o:p>

 <o:p>

            //Initialize the HeaderText field value.<o:p>

            bfield.ItemTemplate = new GridViewTemplate(ListItemType.Item, col.ColumnName);<o:p>

 <o:p>

            //Add the newly created bound field to the GridView.<o:p>

            GrdDynamic.Columns.Add(bfield);<o:p>

        }<o:p>

 <o:p>

        //Initialize the DataSource<o:p>

        GrdDynamic.DataSource = dt;<o:p>

 <o:p>

        //Bind the datatable with the GridView.<o:p>

        GrdDynamic.DataBind();<o:p>

    <o:p>

Let’s start dissecting right from the top,

 <o:p>

  1. Create a DataTable which will hold the table definition and data for the GridView. This table is used as a DataSource for the GridView.
    DataTable dt = new DataTable();
  2. Once the DataTable is created, let’s add 2 columns, ID & Name to the DataTable.
  3. The logic behind creating dynamic column starts by creating a TemplateField instance.
  4. Once the TemplateField is created, I am initializing the HeaderTemplate and ItemTemplate with the newly created GridViewTemplate.We will come back to the GridViewTemplate again.
  5. Once the creation of the dynamic columns is completed, I am assigning the DataSource of the GridView and call the DataBind method to load the GridView with data dynamically.

 <o:p>

Let’s come back to the interesting part of the template columns i.e class GridViewTemplate.<o:p>

//A customized class for displaying the Template Column<o:p>

public class GridViewTemplate : ITemplate<o:p>

{<o:p>

    //A variable to hold the type of ListItemType.<o:p>

    ListItemType _templateType;<o:p>

 <o:p>

    //A variable to hold the column name.<o:p>

    string _columnName;<o:p>

 <o:p>

    //Constructor where we define the template type and column name.<o:p>

    public GridViewTemplate(ListItemType type, string colname)<o:p>

    {<o:p>

        //Stores the template type.<o:p>

        _templateType = type;<o:p>

 <o:p>

        //Stores the column name.<o:p>

        _columnName = colname;<o:p>

    }<o:p>

 <o:p>

    void ITemplate.InstantiateIn(System.Web.UI.Control container)<o:p>

    {<o:p>

        switch (_templateType)<o:p>

        {<o:p>

            case ListItemType.Header:<o:p>

                //Creates a new label control and add it to the container.<o:p>

                Label lbl = new Label();            //Allocates the new label object.<o:p>

                lbl.Text = _columnName;             //Assigns the name of the column in the lable.<o:p>

                container.Controls.Add(lbl);        //Adds the newly created label control to the container.<o:p>

                break;<o:p>

 <o:p>

            case ListItemType.Item:<o:p>

                //Creates a new text box control and add it to the container.<o:p>

                TextBox tb1 = new TextBox();                            //Allocates the new text box object.<o:p>

                tb1.DataBinding += new EventHandler(tb1_DataBinding);   //Attaches the data binding event.<o:p>

                tb1.Columns = 4;                                        //Creates a column with size 4.<o:p>

                container.Controls.Add(tb1);                            //Adds the newly created textbox to the container.<o:p>

                break;<o:p>

 <o:p>

            case ListItemType.EditItem:<o:p>

                //As, I am not using any EditItem, I didnot added any code here.<o:p>

                break;<o:p>

 <o:p>

            case ListItemType.Footer:<o:p>

                CheckBox chkColumn = new CheckBox();<o:p>

                chkColumn.ID = "Chk" + _columnName;<o:p>

                container.Controls.Add(chkColumn);<o:p>

                break;<o:p>

        }<o:p>

    }<o:p>

 <o:p>

    /// <summary><o:p>

    /// This is the event, which will be raised when the binding happens.<o:p>

    /// </summary><o:p>

    /// <param name="sender"></param><o:p>

    /// <param name="e"></param><o:p>

    void tb1_DataBinding(object sender, EventArgs e)<o:p>

    {<o:p>

        TextBox txtdata = (TextBox)sender;<o:p>

        GridViewRow container = (GridViewRow)txtdata.NamingContainer;<o:p>

        object dataValue = DataBinder.Eval(container.DataItem, _columnName);<o:p>

        if (dataValue != DBNull.Value)<o:p>

        {<o:p>

            txtdata.Text = dataValue.ToString();<o:p>

        }<o:p>

    }<o:p>

}

 <o:p>

Any class that should be used as a template should be inherited from the ITemplate class.

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

 <o:p>

One of the interesting method in the ITemplate class is InstantiateIn(Control Container),which defines the Control object that child controls and templates belong to. These child controls are in turn defined within an inline template.

 <o:p>

In the InstanceIn method, based on the _templateType selected, I am creating the necessary controls.

 <o:p>

That’s all your dynamic GridView is ready. I hope this information would be helpful.

 <o:p>

There is another interesting scenario, I would like to bring forward. i.e let’s assume that we have added a button control to the page. Upon user clicking on the button control, the page gets post back. Once the page postback, and if we don’t create the template column again upon post back, the controls would disappear. This is one of the drawbacks of this approach.

 <o:p>

Enjoy programming.

 

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)


Written By
Founder Articledean.com & conveygreetings.com
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 2 Pin
Member 1144948317-May-16 0:52
Member 1144948317-May-16 0:52 
QuestionCan We add both textbox and Label In the Item Template Pin
kishi0115-Dec-15 6:07
kishi0115-Dec-15 6:07 
Questionwhat about edited values getting saved back to the datatable? Pin
Yadav Vinay19-Oct-15 16:13
Yadav Vinay19-Oct-15 16:13 
QuestionSimple and valuable piece of work Pin
Chandra Prasad Khanal16-Oct-15 1:15
Chandra Prasad Khanal16-Oct-15 1:15 
QuestionPaging issue Pin
syedimmadali28-Sep-15 22:04
syedimmadali28-Sep-15 22:04 
Questiontextbox value after postback Pin
AnirbanM 217-Dec-13 2:00
professionalAnirbanM 217-Dec-13 2:00 
Questionobject dataValue = DataBinder.Eval(container.DataItem, _columnName) is not working with entity object Pin
Member 361874720-Oct-13 4:06
Member 361874720-Oct-13 4:06 
AnswerRe: object dataValue = DataBinder.Eval(container.DataItem, _columnName) is not working with entity object Pin
Bunty Arslan6-Nov-14 23:28
Bunty Arslan6-Nov-14 23:28 
GeneralMy vote of 5 Pin
Member 1024089329-Aug-13 7:56
Member 1024089329-Aug-13 7:56 
GeneralMy vote of 5 Pin
Member 448922616-Aug-13 19:10
Member 448922616-Aug-13 19:10 
QuestionIn VB format??? Pin
Member 997393230-Jul-13 5:05
Member 997393230-Jul-13 5:05 
GeneralMy vote of 5 Pin
yasar3120-May-13 2:48
yasar3120-May-13 2:48 
QuestionAdding Web User Control(.ascx) in GridView Pin
Rj_India25-Oct-12 2:47
Rj_India25-Oct-12 2:47 
GeneralMy vote of 4 Pin
Satish Kumar Trivedi23-Aug-12 5:20
Satish Kumar Trivedi23-Aug-12 5:20 
QuestionHey i have question regarding this gridview. Pin
jindi12320-Aug-12 19:24
jindi12320-Aug-12 19:24 
AnswerRe: Hey i have question regarding this gridview. Pin
AnirbanM 217-Dec-13 2:03
professionalAnirbanM 217-Dec-13 2:03 
GeneralRe: Hey i have question regarding this gridview. Pin
Member 1118797728-Oct-14 14:05
Member 1118797728-Oct-14 14:05 
Questionadding html in gridview item template dynamically Pin
Anoop kumar singh9-Jun-12 12:13
Anoop kumar singh9-Jun-12 12:13 
GeneralMy vote of 5 Pin
sravani.v20-May-12 20:11
sravani.v20-May-12 20:11 
QuestionAdding a Pager to the GridView Pin
cUbeindaclUb17-Apr-12 4:10
cUbeindaclUb17-Apr-12 4:10 
QuestionGetting Problem Pin
kapilpandit18-Feb-12 0:47
kapilpandit18-Feb-12 0:47 
AnswerRe: Getting Problem Pin
Member 325336310-Mar-12 14:43
Member 325336310-Mar-12 14:43 
GeneralMy vote of 5 Pin
ElBilo11-Apr-11 15:32
ElBilo11-Apr-11 15:32 
Generaladding the edititm template - issue Pin
ElBilo11-Apr-11 15:30
ElBilo11-Apr-11 15:30 
I really appreciate your efforts in this area. It got me quite a ways on this project but now I find myself stumped.

I've tried to extend your code (after translating it into VB.net) to add the editItem templates. The problem I'm having is that when I try to place the grid row into edit mode by setting the editIndex nothing happens. I've traced execution using the debugger, it seems to be going through the motions but I get nothing back on the browser.

here's what I've done. Maybe you or someone else can see where I went wrong.

apsx page code (only the good parts):

Private Sub bind2gridview()
        BuildGridView(ExcelData.rawdata)
        gvRawData.DataSource = ExcelData.rawdata
        gvRawData.DataBind()
    End Sub


Private Sub BuildGridView(ByRef ds As DataSet)

        If IsNothing(ds) Then Exit Sub ' no point in doing anything without some data()
        '  Clear any existing column definitions on the in the gridview
        gvRawData.Columns.Clear()

        ' iterate through the datatable and create a template for each column
        Dim dc As DataColumn

        If ds.Tables.Count > 0 Then
            'Building all the columns in the table.
            For Each dc In ds.Tables(0).Columns
                'dc.Ordinal
                Dim bfield As TemplateField = New TemplateField()
                bfield.HeaderTemplate = New GridViewTemplate(ListItemType.Header, dc.ColumnName)
                bfield.ItemTemplate = New GridViewTemplate(ListItemType.Item, dc.ColumnName)
                bfield.EditItemTemplate = New GridViewTemplate(ListItemType.EditItem, dc.ColumnName)
                gvRawData.Columns.Add(bfield)
            Next
        End If

    End Sub


This part is suppose to insert a new row into the gridview (gvrawdata) and put that row into edit mode:

Private Sub btnInsertHeaders_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnInsertHeaders.Click
        ExcelData.insertRow()
        gvRawData.EditIndex = 0     ' place the newly inserted row into edit mode.
        bind2gridview()
        UpdatCellContent.Update()   ' updates the ajax updatepanel
    End Sub


the following is the "custom gridview code:

Public Class GridViewTemplate
    Implements ITemplate
    '
    ' Use to generate dynamic customized gridview cell/header templates
    '
    ' reference: http://www.codeproject.com/script/Articles/ViewDownloads.aspx?aid=13462
    '
    Dim _templateType As ListItemType
    Dim _colName As String

    Public Sub New(ByVal type As ListItemType, ByVal value As String, Optional ByVal attrib(,) As String = Nothing)
        _templateType = type
        _colName = value
    End Sub

    Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn
        ' this creates the gridview templates
        Select Case _templateType
            Case ListItemType.Header
                Dim lbl As Label = New Label()
                lbl.Text = _colName
                container.Controls.Add(lbl)

            Case ListItemType.Item
                Dim lblBtn As Label = New Label()
                AddHandler lblBtn.DataBinding, AddressOf lbl_databinding
                container.Controls.Add(lblBtn)

            Case ListItemType.EditItem
                ' no code here as were are not using the gridview's edit function
                Dim dropdown As DropDownList = New DropDownList
                AddHandler dropdown.DataBinding, AddressOf dropdown_dataBinding
                container.Controls.Add(dropdown)
            Case ListItemType.Footer
                ' no code here as we are not using the footer (at this time)
        End Select
    End Sub

    Private Sub anchr_dataBinding(ByVal sender As Object, ByVal e As EventArgs)
        Dim sprdSht As ExcelObject = New ExcelObject()
        Dim anchrData As HtmlAnchor = CType(sender, HtmlAnchor)
        Dim container As GridViewRow = CType(anchrData.NamingContainer, GridViewRow)
        Dim datavalue As Object = DataBinder.Eval(container.DataItem, _colName)
        Dim rowidx As Int32 = container.RowIndex
        If Not IsDBNull(datavalue) Then anchrData.InnerText =
            datavalue.ToString() + "{" + rowidx.ToString + "," + _colName + "}"
        Dim reg As Regex = New Regex("(\d+)")
        Dim colidx As Int32 = reg.Match(_colName).Groups(1).Value
        Dim celldata As CellObject = sprdSht.cell(colidx, rowidx)
        If celldata.definition.Recognition = stat.RecognizedWord Then anchrData.Attributes.Item("class") = "RecognizedTerm"
        If celldata.definition.Recognition = stat.UndefinedWord Then anchrData.Attributes.Item("class") = "undefinedTerm"
        If celldata.definition.Recognition = stat.numericValue Then anchrData.Attributes.Item("class") = "numericValue"
        If celldata.definition.Recognition = stat.emptyCell Then anchrData.Attributes.Item("class") = "emptyCell"
        If celldata.definition.Recognition = stat.commentCell Then anchrData.Attributes.Item("class") = "commentCell"
        anchrData.Attributes.Item("onClick") = "cellClicked(this, " + celldata.definition.rowDesignation.ToString() + ", " +
            celldata.definition.columnIndex.ToString() + ", '" + celldata.definition.wordGroup + "', '" +
            celldata.definition.definition + "')"
    End Sub

    Private Sub lbl_databinding(ByVal sender As Object, ByVal e As EventArgs)
        Dim sprdSht As ExcelObject = New ExcelObject()
        Dim lblData As Label = CType(sender, Label)
        Dim container As GridViewRow = CType(lblData.NamingContainer, GridViewRow)
        Dim dataValue As Object = DataBinder.Eval(container.DataItem, _colName)
        If Not IsDBNull(dataValue) Then
            lblData.Text = dataValue.ToString()
            lblData.ClientIDMode = ClientIDMode.Static
            Dim rowidx As Int32 = container.RowIndex
            Dim reg As Regex = New Regex("(\d+)")
            Dim colidx As Int32 = reg.Match(_colName).Groups(1).Value - 1
            Dim gridobj As GridView = CType(container.NamingContainer, GridView)
            Dim idx As Int16 = gridobj.PageIndex
            rowidx = rowidx + idx * gridobj.PageSize
            Try
                Dim celldata As CellObject = sprdSht.cell(colidx, rowidx)
                If celldata.definition.Recognition = stat.RecognizedWord Then lblData.CssClass = "RecognizedTerm"
                If celldata.definition.Recognition = stat.UndefinedWord Then lblData.CssClass = "undefinedTerm"
                If celldata.definition.Recognition = stat.numericValue Then lblData.CssClass = "numericValue"
                If celldata.definition.Recognition = stat.emptyCell Then lblData.CssClass = "emptyCell"
                If celldata.definition.Recognition = stat.commentCell Then lblData.CssClass = "commentCell"
            Catch ex As Exception
                rowidx = rowidx
            End Try
            lblData.ID = "cellContent" & rowidx & "_" & colidx
        End If
    End Sub

    Private Sub dropdown_dataBinding(ByVal sender As Object, ByVal e As EventArgs)
        Dim dd As DropDownList = CType(sender, DropDownList)
        dd.DataSource = Dictionary.getKeyHeaderTerms
        dd.DataMember = "headerTerms"
        dd.DataTextField = "term"
        dd.DataBind()
    End Sub

End Class

Public Class CustomGridView

End Class

GeneralRe: adding the edititm template - issue Pin
Member 997393230-Jul-13 5:23
Member 997393230-Jul-13 5:23 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.