How to programmatically add FooterTemplate to a GridView control Let’s say you have a table that dynamically changes. If you do not know the number of columns in the table, you cannot define it at design time. The GridView control will automatically bind to the table and auto-generate the number of columns from a DataTable. Let’s say want to place a checkbox in the footer under each of the columns
Some things you can set at design time, like the stylesheets and the ShowFooter. Set the ShowFooter = True.
Elizabeth Gee
Simple ASP.Net Recipes
1
How to programmatically add FooterTemplate to a GridView control In this example, we are going to show the number of ticket sales that people made each year. In the figure below, notice the footer is empty.
Click on the Event icon and double click in the event: RowCreated. This will automatically create a method in the code behind.
protected void grdViewHistory_RowCreated(object sender, GridViewRowEventArgs e) { } Add the following code to this method:
C# protected void grdViewHistory_RowCreated(object sender, GridViewRowEventArgs e) { //count the number of cells in this row Int32 cellCnt = e.Row.Cells.Count; //if this is the header row, align the first header to the right Elizabeth Gee
Simple ASP.Net Recipes
2
How to programmatically add FooterTemplate to a GridView control if (e.Row.RowType == DataControlRowType.Header) { e.Row.Cells[0].HorizontalAlign = HorizontalAlign.Right; } //else if this is the footer,
}
else if (e.Row.RowType == DataControlRowType.Footer) { //add checkbox to all the columns except the first two for (Int32 i = 2; i < cellCnt; i++) { //Instantiate a new checkbox for each cell. CheckBox chkFooter = new CheckBox(); //Add this checkbox as a control to the footer cell e.Row.Cells[i].Controls.Add(chkFooter); //center the checkbox in the cell e.Row.Cells[i].HorizontalAlign = HorizontalAlign.Center; } }
Visual Basic Protected Sub gridViewHistory_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gridViewHistory.RowCreated 'count the number of cells in this row Dim cellCnt As Integer = e.Row.Cells.Count - 1 'if this is the header row, align the first header to the right If (e.Row.RowType = DataControlRowType.Header) Then e.Row.Cells(0).HorizontalAlign = HorizontalAlign.Right 'else if this is the footer, ElseIf (e.Row.RowType = DataControlRowType.Footer) Then 'add checkbox to all the columns except the first two For i As Integer = 2 To cellCnt 'Instantiate a new checkbox for each cell. Dim chkFooter As New CheckBox() 'Add this checkbox as a control to the footer cell e.Row.Cells(i).Controls.Add(chkFooter) 'center the checkbox in the cell e.Row.Cells(i).HorizontalAlign = HorizontalAlign.Center Next End If End Sub
Elizabeth Gee
Simple ASP.Net Recipes
3
How to programmatically add FooterTemplate to a GridView control
Next we are going to add an event to the footer checkboxes. In this example, when the user clicks on a checkbox in the footer, it will • Change the header Checkbox1 to blue • Display the list of column indexes of the footer checkboxes that are checked. Adding two lines of code to the GridView RowCreated event sets • AutoPostBack = True • Adds an attribute which contains the column index for the year. • Add an event handler
C# protected void grdViewHistory_RowCreated(object sender, GridViewRowEventArgs e)
{ //count the number of cells in this row Int32 cellCnt = e.Row.Cells.Count; //if this is the header row, align the first header to the right if (e.Row.RowType == DataControlRowType.Header) { e.Row.Cells[0].HorizontalAlign = HorizontalAlign.Right; } //else if this is the footer, else if (e.Row.RowType == DataControlRowType.Footer) { //add checkbox to all the columns except the first two for (Int32 i = 2; i < cellCnt; i++) { //Instantiate a new checkbox for each cell. CheckBox chkFooter = new CheckBox(); //Add AutoPostBack chkFooter.AutoPostBack = true; //Add an attribute for the column index chkFooter.Attributes.Add("year", i.ToString());
Elizabeth Gee
Simple ASP.Net Recipes
4
How to programmatically add FooterTemplate to a GridView control //Add an event handler chkFooter.CheckedChanged += chkFooter_CheckedChanged;
}
//Add this checkbox as a control to the footer cell e.Row.Cells[i].Controls.Add(chkFooter); //center the checkbox in the cell e.Row.Cells[i].HorizontalAlign = HorizontalAlign.Center;
}
}
Visual Basic Protected Sub gridViewHistory_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gridViewHistory.RowCreated 'count the number of cells in this row Dim cellCnt As Integer = e.Row.Cells.Count - 1 'if this is the header row, align the first header to the right If (e.Row.RowType = DataControlRowType.Header) Then e.Row.Cells(0).HorizontalAlign = HorizontalAlign.Right 'else if this is the footer, ElseIf (e.Row.RowType = DataControlRowType.Footer) Then 'add checkbox to all the columns except the first two For i As Integer = 2 To cellCnt 'Instantiate a new checkbox for each cell. Dim chkFooter As New CheckBox() 'Add AutoPostBack chkFooter.AutoPostBack = True 'Add an attribute for the column index chkFooter.Attributes.Add("year", i.ToString()) 'Add an event handler AddHandler chkFooter.CheckedChanged, New EventHandler(AddressOf chkFooter_CheckedChanged) 'Add this checkbox as a control to the footer cell e.Row.Cells(i).Controls.Add(chkFooter) 'center the checkbox in the cell e.Row.Cells(i).HorizontalAlign = HorizontalAlign.Center Next End If End Sub
Elizabeth Gee
Simple ASP.Net Recipes
5
How to programmatically add FooterTemplate to a GridView control
Add another checkbox and a button to the page. In this example CheckBox2 is used to display the columns selected. We will use the button later for calculating totals.
The next step is two write the event handler for the chkFooter. It references the “year” attribute which we added in the RowCreated step above.
C# protected void chkFooter_CheckedChanged(object sender, EventArgs e) { //Changes the Checkbox1 forecolor to MediumBlue CheckBox1.ForeColor = System.Drawing.Color.MediumBlue; //the sender is the chkFooter that was clicked CheckBox chkFooter = (CheckBox)sender; //get the "year" attribute of the chkFooter and append a "|" as a delimiter string idx = chkFooter.Attributes["year"].ToString() + "|";
}
if (chkFooter.Checked) { CheckBox2.Text += idx; //add the idx } else { //remove the idx CheckBox2.Text = CheckBox2.Text.Replace(idx,""); }
Visual Basic Protected Sub chkFooter_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) 'Changes the Checkbox1 forecolor to MediumBlue CheckBox1.ForeColor = System.Drawing.Color.MediumBlue 'the sender is the chkFooter that was clicked Dim chkFooter As CheckBox = DirectCast(sender, CheckBox)
Elizabeth Gee
Simple ASP.Net Recipes
6
How to programmatically add FooterTemplate to a GridView control 'get the "year" attribute of the chkFooter and append a "|" as a delimiter Dim idx As String = chkFooter.Attributes("year").ToString() & "|" If chkFooter.Checked Then 'add the idx CheckBox2.Text += idx Else 'remove the idx CheckBox2.Text = CheckBox2.Text.Replace(idx, "") End If End Sub
Next we are going to add functionality to fill the Totals column. The totals column displays the sum of the year cells in each row. Notice that the numbers are formatted. You can format these numbers in the DataTable before initially binding to the GridView control.
Below are a couple of functions for numeric formatting of integers with and without commas:
Elizabeth Gee
Simple ASP.Net Recipes
7
How to programmatically add FooterTemplate to a GridView control C# public string AddCommas(Int32 value) { return value.ToString("N0"); } public Int32 RemoveCommas(string value) { value = value.Replace(",", ""); return Convert.ToInt32(value); }
Visual Basic Public Function AddCommas(ByVal value) As String Return value.ToString("N0"); End Function Public Function RemoveCommasInt32(ByVal value As String) As Int32 value = value.Replace(",", "") Return Convert.ToInt32(value) End Function Below are a couple of methods for calculating the totals and changing the font color for the checked column:
C# protected void TotalYearColumns() { int years = grdViewHistory.Rows[0].Cells.Count; int rows = grdViewHistory.Rows.Count; for (int r = 0; r < rows; r++) { GridViewRow gridRow = grdViewHistory.Rows[r]; Int32 total = 0; for (int c = 2; c < years; c++) { if (gridRow.Cells[c].ForeColor != System.Drawing.Color.Silver) { total += Convert.ToInt32(RemoveCommas(gridRow.Cells[c].Text)); } } gridRow.Cells[1].Text = AddCommas(total); } }
Visual Basic Protected Sub TotalYearColumns() Dim years As Integer = grdViewHistory.Rows(0).Cells.Count Dim rows As Integer = grdViewHistory.Rows.Count For r As Integer = 0 To rows - 1 Dim gridRow As GridViewRow = grdViewHistory.Rows(r) Dim total As Int32 = 0 Elizabeth Gee
Simple ASP.Net Recipes
8
How to programmatically add FooterTemplate to a GridView control For c As Integer = 2 To years - 1 If gridRow.Cells(c).ForeColor <> System.Drawing.Color.Silver Then total += Convert.ToInt32(RemoveCommas(gridRow.Cells(c).Text)) End If Next gridRow.Cells(1).Text = AddCommas(total) Next End Sub
Add this method to the button event for the Calculate button:
C# protected void btnCalculate_Click(object sender, EventArgs e) { TotalYearColumns(); }
Visual Basic Protected Sub btnCalculate_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnCalculate.Click TotalYearColumns() End Sub Run the page and click on the button to fill the Totals column:
Next we are going to add the ToggleYearColumns method to the chkFooter_CheckChanged event:
C# protected void ToggleYearColumns(Int32 idx, bool isChecked) { Elizabeth Gee
Simple ASP.Net Recipes
9
How to programmatically add FooterTemplate to a GridView control int years = grdViewHistory.Rows[0].Cells.Count; int rows = grdViewHistory.Rows.Count; for (int r = 0; r < rows; r++) { if (isChecked) { grdViewHistory.Rows[r].Cells[idx].ForeColor = System.Drawing.Color.Silver; } else { grdViewHistory.Rows[r].Cells[idx].ForeColor = grdViewHistory.Rows[r].Cells[1].ForeColor; } } } protected void chkFooter_CheckedChanged(object sender, EventArgs e) { //Changes the Checkbox1 forecolor to MediumBlue CheckBox1.ForeColor = System.Drawing.Color.MediumBlue; //the sender is the chkFooter that was clicked CheckBox chkFooter = (CheckBox)sender; //get the "year" attribute of the chkFooter and append a "|" as a delimiter Int32 index = Convert.ToInt32(chkFooter.Attributes["year"]); string idx = index.ToString() + "|"; if (chkFooter.Checked) { CheckBox2.Text += idx; //add the idx } else { CheckBox2.Text = CheckBox2.Text.Replace(idx,""); } ToggleYearColumns(index, chkFooter.Checked);
//remove the idx
}
Visual Basic Protected Dim Dim For
Sub ToggleYearColumns(ByVal idx As Int32, ByVal isChecked As Boolean) years As Integer = grdViewHistory.Rows(0).Cells.Count rows As Integer = grdViewHistory.Rows.Count r As Integer = 0 To rows - 1 If isChecked Then grdViewHistory.Rows(r).Cells(idx).ForeColor = System.Drawing.Color.Silver Else grdViewHistory.Rows(r).Cells(idx).ForeColor = grdViewHistory.Rows(r).Cells(1).ForeColor End If Next Elizabeth Gee
Simple ASP.Net Recipes
10
How to programmatically add FooterTemplate to a GridView control End Sub Protected Sub chkFooter_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) 'Changes the Checkbox1 forecolor to MediumBlue CheckBox1.ForeColor = System.Drawing.Color.MediumBlue 'the sender is the chkFooter that was clicked Dim chkFooter As CheckBox = DirectCast(sender, CheckBox) 'get the "year" attribute of the chkFooter and append a "|" as a delimiter Dim index As Int32 = Convert.ToInt32(chkFooter.Attributes("year")) Dim idx As String = index.ToString() & "|" If chkFooter.Checked Then 'add the idx CheckBox2.Text += idx Else 'remove the idx CheckBox2.Text = CheckBox2.Text.Replace(idx, "") End If ToggleYearColumns(index, chkFooter.Checked) End Sub Run the page and click on the checkboxes in the footer. Notice how the column font color toggles from Black to Silver. Click on the Calculate button. Notice how the Totals column only totals the columns that are not grayed out.
Elizabeth Gee
Simple ASP.Net Recipes
11
How to programmatically add FooterTemplate to a GridView control
Adding a Footer Caption and Black Gridlines In a dynamically generated grid, you can add a footer caption / header in the RowCreated method. You might want to add vertical colored gridlines which in Design mode is set in the ItemStyle, however when dynamically adding columns to a grid, the ItemStyle can be added in the RowCreated method. First add a class in your style sheet: <style type="text/css"> .wgi { border-right: solid 1px black;} Next add some code to the RowCreated method as highlighted in yellow below. To add the caption to the first cell in the footer, scroll down to the else if (e.Row.RowType == DataControlRowType.Footer) and add the caption text to Cell[0] of the footer row.
C# e)
protected void grdViewHistory_RowCreated(object sender, GridViewRowEventArgs {
//count the number of cells in this row Int32 cellCnt = e.Row.Cells.Count; //add gridline Css for all rows including header for (int i = 0; i < cellCnt; i++) { e.Row.Cells[i].CssClass = "wgi"; } //if this is the header row, align the first header to the right if (e.Row.RowType == DataControlRowType.Header) { e.Row.Cells[0].HorizontalAlign = HorizontalAlign.Right; } //else if this is the footer, else if (e.Row.RowType == DataControlRowType.Footer) { TableCell footerCell = e.Row.Cells[0]; footerCell.Text = "Exclude year(s)"; footerCell.HorizontalAlign = HorizontalAlign.Right; //add checkbox to all the columns except the first two for (Int32 i = 2; i < cellCnt; i++) { //Instantiate a new checkbox for each cell. CheckBox chkFooter = new CheckBox(); //Add AutoPostBack chkFooter.AutoPostBack = true; //Add an attribute for the column index chkFooter.Attributes.Add("year", i.ToString()); //Add an event handler chkFooter.CheckedChanged += chkFooter_CheckedChanged;
Elizabeth Gee
Simple ASP.Net Recipes
12
How to programmatically add FooterTemplate to a GridView control //Add this checkbox as a control to the footer cell e.Row.Cells[i].Controls.Add(chkFooter); //center the checkbox in the cell e.Row.Cells[i].HorizontalAlign = HorizontalAlign.Center; e.Row.Cells[i].CssClass = "wgi"; }
}
}
Visual Basic Protected Sub gridViewHistory_RowCreated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gridViewHistory.RowCreated 'count the number of cells in this row Dim cellCnt As Integer = e.Row.Cells.Count - 1 'add gridline Css for all rows including header For i As Integer = 0 To cellCnt - 1 e.Row.Cells(i).CssClass = "wgi" Next 'if this is the header row, align the first header to the right If (e.Row.RowType = DataControlRowType.Header) Then e.Row.Cells(0).HorizontalAlign = HorizontalAlign.Right 'else if this is the footer, ElseIf (e.Row.RowType = DataControlRowType.Footer) Then Dim footerCell As TableCell = e.Row.Cells(0) footerCell.Text = "Exclude year(s)" footerCell.HorizontalAlign = HorizontalAlign.Right 'add checkbox to all the columns except the first two For i As Integer = 2 To cellCnt 'Instantiate a new checkbox for each cell. Dim chkFooter As New CheckBox() 'Add AutoPostBack chkFooter.AutoPostBack = True 'Add an attribute for the column index chkFooter.Attributes.Add("year", i.ToString()) 'Add an event handler AddHandler chkFooter.CheckedChanged, New EventHandler(AddressOf chkFooter_CheckedChanged) 'Add this checkbox as a control to the footer cell e.Row.Cells(i).Controls.Add(chkFooter) 'center the checkbox in the cell e.Row.Cells(i).HorizontalAlign = HorizontalAlign.Center e.Row.Cells(i).CssClass = "wgi" Next End If End Sub
Elizabeth Gee
Simple ASP.Net Recipes
13
How to programmatically add FooterTemplate to a GridView control
Calculating without the button If you want to re-calculate the totals when you click the footer checkboxes instead of using the additional Calculate button, move the call to TotalYearColumns() to the chkFooter_CheckChanged event. To clean this simple recipe up, you can remove the button and CheckBox2 which were used as examples. Remember to remove the code which references them
C# protected void chkFooter_CheckedChanged(object sender, EventArgs e) { //Changes the Checkbox1 forecolor to MediumBlue CheckBox1.ForeColor = System.Drawing.Color.MediumBlue; //the sender is the chkFooter that was clicked CheckBox chkFooter = (CheckBox)sender; //get the "year" attribute of the chkFooter and append a "|" as a delimiter Int32 index = Convert.ToInt32(chkFooter.Attributes["year"]); //string idx = index.ToString() + "|";
}
//if (chkFooter.Checked) //{ // CheckBox2.Text += idx; //add the idx //} //else //{ // CheckBox2.Text = CheckBox2.Text.Replace(idx,""); //} ToggleYearColumns(index, chkFooter.Checked); TotalYearColumns();
Elizabeth Gee
Simple ASP.Net Recipes
//remove the idx
14
How to programmatically add FooterTemplate to a GridView control Visual Basic Protected Sub chkFooter_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) 'Changes the Checkbox1 forecolor to MediumBlue CheckBox1.ForeColor = System.Drawing.Color.MediumBlue 'the sender is the chkFooter that was clicked Dim chkFooter As CheckBox = DirectCast(sender, CheckBox) 'get the "year" attribute of the chkFooter and append a "|" as a delimiter Dim index As Int32 = Convert.ToInt32(chkFooter.Attributes("year")) 'Dim idx As String = index.ToString() & "|" 'If chkFooter.Checked Then ' 'add the idx ' CheckBox2.Text += idx 'Else ' 'remove the idx ' CheckBox2.Text = CheckBox2.Text.Replace(idx, "") 'End If ToggleYearColumns(index, chkFooter.Checked) TotalYearColumns() End Sub
Elizabeth Gee
Simple ASP.Net Recipes
15