Introduction
This is my first article, hope I'm doing it correct, I don't want to bore you with too much talk, so it's pretty much code, hope it suffices. I wanted a simple and& sort of generic approach to add summary totals to the footer record of a data repeater.
Background
My need was for a datatable that gets bound to a
Repeater
, plain and simple, with a summary total for the amount and count columns for every report I had to do. The table is a report coming straight from SQL Server via my backend.
Using the code
I have added all the code into this one file, so you can just copy it into any ASP.NET project and just run it.
- First we need a private variable to hold the summary totals for the fields in the table that need to be summarized.
#region - Private variables -
private Dictionary<string, decimal> totals = new Dictionary<string, decimal>();
#endregion
- The next bit of code is purely to add sample data into the datatable. The data for the actual report will obviously come from your data source.
#region - This code belong in your backend -
private void addDataColumn(DataTable table, string colName, string colType, bool colNull, object colDefault)
{
DataColumn column = new DataColumn();
column.DataType = System.Type.GetType(colType);
column.ColumnName = colName;
column.AllowDBNull = colNull;
column.DefaultValue = colDefault;
table.Columns.Add(column);
}
private DataTable createDataTable()
{
DataTable dtData = new DataTable();
addDataColumn(dtData, "RecordId", "System.Int32", false, 0);
addDataColumn(dtData, "Description", "System.String", false, 0);
addDataColumn(dtData, "TotalCount", "System.Int32", false, 0);
addDataColumn(dtData, "TotalAmount", "System.Decimal", false, 0);
for (int i = 1; i < 6; ++i)
{
DataRow dr = dtData.NewRow();
dr["RecordId"] = i;
dr["Description"] = "Description for row " + i;
dr["TotalCount"] = i;
dr["TotalAmount"] = i * 3.34m;
dtData.Rows.Add(dr);
}
dtData.AcceptChanges();
return dtData;
}
#endregion
- The next method is the generic part that loops the table and summarize the fields that you've added in a dictionary. Again, I've added this method to a static helper class because you can then re-use it.
private void sumDataTable(DataTable dt, Dictionary<string, decimal> totals)
{
List<string> keyList = new List<string>(totals.Keys);
for (int i = 0; i < dt.Rows.Count; ++i)
{
foreach (string key in keyList)
{
totals[key] += Convert.ToDecimal(dt.Rows[i][key]);
}
}
}
- Now we have the source code specifically to the report form, starting with the page load.
protected void Page_Load(object sender, EventArgs e)
{
bindTableToForm();
}
and then in my bind region, we have:
- Create and get the sample data.
- Add the columns that needs to be totaled into the
Dictionary<fieldName, startvalue>
. - Bind your data.
#region - Bind Methods -
private void bindTableToForm()
{
DataTable dtReport = createDataTable();
totals.Add("TotalCount", 0);
totals.Add("TotalAmount", 0);
sumDataTable(dtReport, totals);
rprData.DataSource = dtReport;
rprData.DataBind();
}
#endregion
- We need to add a protected / public method to the page for the
Repeater
to access the summary totals in the dictionary.
#region - Public methods -
protected string getTotalFor(string field, string formatString)
{
decimal value = 0;
totals.TryGetValue(field, out value);
return value.ToString(formatString);
}
#endregion
- And finally the ASP.NET HTML code:
<%@ Page Language="C#" AutoEventWireup="true"
CodeBehind="RepeaterSummaryTotal.aspx.cs" Inherits="IQ.Web.RepeaterSummaryTotal" %>
<!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>
<div id="reportResults">
<br />
<asp:Repeater ID="rprData" runat="server">
<HeaderTemplate>
<table id="tblData"">
<thead>
<tr>
<th colspan="4">
Report sample
</th>
</tr>
<tr>
<td>
Id.
</td>
<td>
Description
</td>
<td style="text-align:right">
Total count
</td>
<td style="text-align:right">
Total amount
</td>
</tr>
</thead>
</HeaderTemplate>
<ItemTemplate>
<tr class="even">
<td>
<%# Eval("RecordId")%>
</td>
<td>
<%# Eval("Description")%>
</td>
<td style="text-align:right">
<%# Eval("TotalCount")%>
</td>
<td style="text-align:right">
<%#String.Format("{0:C}", Eval("TotalAmount"))%>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr class="odd">
<td>
<%# Eval("RecordId")%>
</td>
<td>
<%# Eval("Description")%>
</td>
<td style="text-align:right">
<%# Eval("TotalCount")%>
</td>
<td style="text-align:right">
<%#String.Format("{0:C}", Eval("TotalAmount"))%>
</td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
<tr class="subHeadingTr" style="font-weight:bold; background-color: #e8e8e8;">
<td colspan="2">
Totals
</td>
<td style="text-align:right">
<%# getTotalFor("TotalCount","")%>
</td>
<td style="text-align:right">
<%# getTotalFor("TotalAmount","C")%>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</div>
</form>
</body>
</html>