Working with Total, Group, and Custom Summaries in Code
- 10 minutes to read
#Create Total Summaries
The following example creates total summaries (Count, Average, Custom) and displays them in the grid’s footer. The example handles the GridView.CustomSummaryCalculate event to count the number of orders created within the current week.
using System;
using DevExpress.Data;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
namespace GridSummaries
{
public partial class Form1 : RibbonForm
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Load data into the 'nwindDataSet.Orders' table.
this.ordersTableAdapter.Fill(this.nwindDataSet.Orders);
// Create summaries
CreateTotalSummaries();
// Handle the event to calculate a custom summary
gridView.CustomSummaryCalculate += GridView_CustomSummaryCalculate;
// Display a footer with summaries
gridView.OptionsView.ShowFooter = true;
}
void CreateTotalSummaries()
{
GridColumnSummaryItem total = new GridColumnSummaryItem()
{
SummaryType = SummaryItemType.Count,
DisplayFormat = "{0} orders"
};
// Add the total summary to the 'OrderID' column
colOrderID.Summary.Add(total);
GridColumnSummaryItem average = new GridColumnSummaryItem()
{
SummaryType = SummaryItemType.Average,
FieldName = "Freight",
DisplayFormat = "Average: {0:#.#}"
};
// Add the average summary to the 'Freight' column
colFreight.Summary.Add(average);
GridColumnSummaryItem custom = new GridColumnSummaryItem()
{
SummaryType = SummaryItemType.Custom,
FieldName = "OrderDate",
DisplayFormat = "This week: {0:n0} orders"
};
// Add the custom summary to the 'OrderDate' column
colOrderDate.Summary.Add(custom);
}
int orderCount = 0;
private void GridView_CustomSummaryCalculate(object sender, CustomSummaryEventArgs e)
{
GridView view = sender as GridView;
if (e.IsTotalSummary)
{
switch (e.SummaryProcess)
{
// Start calculation
case CustomSummaryProcess.Start:
orderCount = 0;
break;
// Consequent calculations
case CustomSummaryProcess.Calculate:
DateTime today = DateTime.Today;
DateTime orderDate = Convert.ToDateTime(view.GetRowCellValue(e.RowHandle, view.Columns["OrderDate"]));
int currentDayOfWeek = (int)today.DayOfWeek;
DateTime startOfWeek = today.AddDays(-currentDayOfWeek + (currentDayOfWeek == 0 ? -6 : 1)); // Start on Monday
DateTime endOfWeek = startOfWeek.AddDays(6); // End on Sunday
if (orderDate.Date >= startOfWeek && orderDate <= endOfWeek)
orderCount++;
break;
// Final summary value
case CustomSummaryProcess.Finalize:
e.TotalValue = orderCount;
break;
}
}
}
}
}
#Create Group Summaries
The following example creates group summary items (Count, Average, Custom). The ‘Count’ summary is displayed in group rows. ‘Average’ and ‘Custom’ summaries are displayed in group footers. To create a group summary, create a GridGroupSummaryItem object, customize its settings, and add the object to the GridView.GroupSummary collection.
using System;
using DevExpress.Data;
using DevExpress.XtraBars.Ribbon;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
namespace GridSummaries
{
public partial class Form1 : RibbonForm
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// Load data into the 'nwindDataSet.Orders' table
this.ordersTableAdapter.Fill(this.nwindDataSet.Orders);
// Create summaries
CreateGroupSummaries();
// Handle the event to calculate a custom summary
gridView.CustomSummaryCalculate += GridView_CustomSummaryCalculate;
// Display a group footer within expanded groups
gridView.OptionsView.GroupFooterShowMode = GroupFooterShowMode.VisibleIfExpanded;
// Group the View by the 'ShipCountry' column
colShipCountry.GroupIndex = 0;
// Expand the first group
gridView.ExpandGroupRow(-1);
}
void CreateGroupSummaries()
{
GridGroupSummaryItem total = new GridGroupSummaryItem()
{
SummaryType = SummaryItemType.Count,
DisplayFormat = "{0} orders"
};
GridGroupSummaryItem average = new GridGroupSummaryItem()
{
SummaryType = SummaryItemType.Average,
FieldName = "Freight",
DisplayFormat = "Average: {0:#.#}",
ShowInGroupColumnFooter = colFreight
};
GridGroupSummaryItem custom = new GridGroupSummaryItem()
{
SummaryType = SummaryItemType.Custom,
FieldName = "OrderDate",
DisplayFormat = "This week: {0:n0} orders",
ShowInGroupColumnFooter = colOrderDate
};
// Add group summary items to the 'GroupSummary' collection
gridView.GroupSummary.AddRange(new GridSummaryItem[]{
total, average, custom
});
}
int orderCount = 0;
private void GridView_CustomSummaryCalculate(object sender, CustomSummaryEventArgs e)
{
GridView view = sender as GridView;
if (e.IsGroupSummary)
{
switch (e.SummaryProcess)
{
// Start calculation
case CustomSummaryProcess.Start:
orderCount = 0;
break;
// Consequent calculations
case CustomSummaryProcess.Calculate:
DateTime today = DateTime.Today;
DateTime orderDate = Convert.ToDateTime(view.GetRowCellValue(e.RowHandle, view.Columns["OrderDate"]));
int currentDayOfWeek = (int)today.DayOfWeek;
DateTime startOfWeek = today.AddDays(-currentDayOfWeek + (currentDayOfWeek == 0 ? -6 : 1)); // Start on Monday
DateTime endOfWeek = startOfWeek.AddDays(6); // End on Sunday
if (orderDate.Date >= startOfWeek && orderDate <= endOfWeek)
orderCount++;
break;
// Final summary value
case CustomSummaryProcess.Finalize:
e.TotalValue = orderCount;
break;
}
}
}
}
}
#Obtain Summary Values
Use the following API to obtain summaries, aggregated values (summary values), and formatted summary text displayed in footer cells.
Note
In master detail mode, when a master row is expanded, the Data Grid creates a Pattern View to display detail data. Pattern Views only store settings and are never connected to data. To access summaries in detail views, use columns and summaries of clone Views.
Refer to the following help topic for additional information: Master-Detail Relationships.
#Common API
API Member | Description |
---|---|
Grid |
Gets the value of the summary item. |
Grid |
Returns the formatted summary value as a string. |
using DevExpress.XtraGrid;
...
// Create a total summary that calculates the total number of employees
GridColumnSummaryItem summary = new GridColumnSummaryItem(DevExpress.Data.SummaryItemType.Count, "EmployeeID", "{0} Employees") { Tag = "Employees" };
gridView.Columns["EmployeeID"].Summary.Add(summary);
// Display a footer with total summaries
gridView.OptionsView.ShowFooter = true;
...
// Obtain a total summary value
object count = colEmployeeID.Summary["Employees"].SummaryValue;
#Total Summaries
API Member | Description |
---|---|
Returns the text displayed by total summaries owned by this column. The return value is a string that delimits values of separate summaries with the |
#Group Summaries
API Member | Description |
---|---|
Takes a row handle and a column as parameters and returns a
| |
Return the value and display text of the specified group summary item displayed in the specified group row. | |
Returns a hashtable that stores summary items (keys) and their values for the specified group row. The hashtable contains entries for summary items displayed in both group footers and group rows. | |
Returns the group summary item’s text displayed in the specified group row. | |
Returns the group summary item’s text displayed in the specified group footer cell. |
#Example: Obtain Summary Values
The following code snippet does the following:
- Highlights group rows that contain more than 30 rows.
- Highlights the total summary in the “Freight” column if the total summary value is greater than 40.
using System.Drawing;
using DevExpress.XtraGrid;
using DevExpress.XtraGrid.Views.Grid;
// Highlight a total summary
private void GridView_CustomDrawFooterCell(object sender, FooterCellCustomDrawEventArgs e)
{
if(e.Column == colFreight) {
GridSummaryItem summary = e.Info.SummaryItem;
double summaryValue = Convert.ToDouble(summary.SummaryValue);
if (summaryValue > 40)
e.Appearance.ForeColor = Color.Red;
}
}
// Highlight group rows based on a condition
private void GridView_RowStyle(object sender, RowStyleEventArgs e)
{
GridView view = sender as GridView;
if (view == null) return;
if (e.RowHandle >= 0 || view.GroupCount == 0) return;
// Get all group summary values
Hashtable ht = view.GetGroupSummaryValues(e.RowHandle);
// Obtain the first group summary
GridSummaryItem groupSummaryItem = view.GroupSummary[0];
// Obtain the group summary's value
int childRecordCount = Convert.ToInt32(ht[groupSummaryItem]);
if (childRecordCount > 30)
e.Appearance.BackColor = Color.FromArgb(70, Color.Yellow);
}
#Update Summaries
The WinForms Data Grid updates summaries when a user focuses a row or presses the End Init Data Navigator button. You can disable this automatic update for total summaries to improve overall grid performance with large data sources. To do this, disable the View’s OptionsBehavior.AutoUpdateTotalSummary option.
Use one of the following methods to forcibly update summaries when needed:
- GridView.UpdateTotalSummary() — Recalculates values for all total summaries.
- GridView.UpdateGroupSummary() — Recalculates values for all group summaries.
- GridView.UpdateSummary() — Updates both total and group summaries.
The following code snippet updates total summaries after the user changes a value in the “Quantity” column:
gridView1.CellValueChanged += GridView1_CellValueChanged;
private void GridView1_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
{
GridView view = sender as GridView;
if (e.Column == colQuantity)
{
view.UpdateTotalSummary();
}
}