Click here to Skip to main content
14,302,993 members

Cross-Tab Reports : Dynamically add columns to grid

Rate this:
2.00 (5 votes)
Please Sign up or sign in to vote.
2.00 (5 votes)
9 Sep 2007
Article describing how to work of girds which needs to add columns dynamically at run time.


All of us might have used grids for showing reports in asp .net. Normally when we show a report in grid the no of columns will be fixed. Rows that can come in the reports, may very depends on a no of factors. Cross tab reports are something where the row as well as the no of columns will very as per the condition user provided with. So when you use grids for showing those types of reports, you have to build the columns dynamically.


For a more clear explanation let us work with an example. In this you have a simple database where you have got 'n' no of students from different departments in a table and their marks in another table. When I say they are from different department I mean that the no of paper they will study will also very. Lets say department1 have got 2 paper and department2 got 1 paper. So in the mark sheet of a student from department 1 you can see the mark of both paper1 and paper2. While in the mark sheet of a student from department2 you can see only mark for a single paper.

Using the code

Screenshot - CrossStar.jpg

Let's see how we can build our business object for this. We need to have a 'subject' business object for saving his mark, and a 'Student' business object with his name and list of marks. It can be like

Screenshot - CrossStarExample.jpg

So for filling the object we need to fill the data for student first and then make objects of subject and add it to the list in mark list. For cross tab implantation we can give this object as the data source to the grid. Then before binding we can add columns that are needed dynamically.

For bound field we can directly assign its header text and data field.

Private Function GetBoundColumn(ByVal hText As String, ByVal datafield As String) As BoundField 

  Dim newColumn As BoundField 
       newColumn = New BoundField() 

              With newColumn 
                     .HeaderText = hText 
                     .DataField = datafield 
              End With 
       Return newColumn
End Function

For template columns we need to make use of a class implementing ITemplate interface.

Private Function GetTemplateColumn(ByVal dSource As List(Of Types), ByVal colId As Integer) As TemplateField 

Dim newColumn As TemplateField 
       newColumn = New TemplateField() 
       With newColumn 
              .HeaderTemplate = New TemplateFactory("M" & colId, DataControlRowType.Header, 0) 
              .ItemTemplate = New TemplateFactory("", DataControlRowType.DataRow, colId) 
       End With 

       Return newColumn 
End Function

Public Class TemplateFactory 
              Implements ITemplate 

Dim _hdrName As String 
Dim _rowType As DataControlRowType 
Dim _colId As Integer 

Public Sub New(ByVal hdrName As String, ByVal rowType As DataControlRowType, ByVal colId As Integer) 
       _hdrName = hdrName 
       _rowType = rowType 
       _colId = colId 
End Sub 

Public Sub InstantiateIn(ByVal container As System.Web.UI.Control) Implements System.Web.UI.ITemplate.InstantiateIn 
       If (_rowType = DataControlRowType.Header) Then 
              Dim oLabel As New Label() 
              oLabel.Text = _hdrName 
              oLabel.ForeColor = Drawing.Color.White 
       ElseIf (_rowType = DataControlRowType.DataRow) Then 
              Dim oTextBox As New TextBox() 

              oTextBox.ID = _colId 
              AddHandler oTextBox.DataBinding, AddressOf TextBox1_DataBinding 
       End If 
End Sub 

Protected Sub TextBox1_DataBinding(ByVal sender As Object, ByVal e As System.EventArgs) 
Dim txt As TextBox 
Dim gvRow As GridViewRow 
Dim i As Integer 

           txt = CType(sender, TextBox) 
           gvRow = CType(txt.NamingContainer, GridViewRow) 
           i = CType(txt.ID, Integer) 

    If (CType(gvRow.DataItem, TypesList).TypeList.Count > i) Then 
              txt.Text = DataBinder.Eval(CType(gvRow.DataItem, TypesList).TypeList(i), "Name") 
           End If 

End Sub 
End Class

Points of Interest

If we have many reports, that needs to have a cross-tab implantation, then we have go for a 'Builder' design pattern for easy implementation. More details about this can be find in the attachment.


Keep a running update of any changes or improvements you've made here.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
Working in Microsoft technologies for the last 4 years

Comments and Discussions

Generalhello can i get C#? hehee Pin
mohdkhasif30-Mar-10 15:11
membermohdkhasif30-Mar-10 15:11 
Generalc# version Pin
adambrowne6-Nov-07 1:24
memberadambrowne6-Nov-07 1:24 
GeneralRe: c# version Pin
apna6-Nov-07 1:30
memberapna6-Nov-07 1:30 
GeneralRe: c# version Pin
Member 1383937722-May-18 7:11
memberMember 1383937722-May-18 7:11 

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.

Posted 9 Sep 2007


27 bookmarked