windowsforms-701-controls-and-libraries-data-grid-summaries-working-with-summaries-in-code-custom-summaries.md
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;
}
}
}
}
}
Imports System
Imports DevExpress.Data
Imports DevExpress.XtraBars.Ribbon
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Views.Grid
Namespace GridSummaries
Partial Public Class Form1
Inherits RibbonForm
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
' Load data into the 'nwindDataSet.Orders' table.
Me.ordersTableAdapter.Fill(Me.nwindDataSet.Orders)
' Create summaries
CreateTotalSummaries()
' Handle the event to calculate a custom summary
AddHandler gridView.CustomSummaryCalculate, AddressOf GridView_CustomSummaryCalculate
' Display a footer with summaries
gridView.OptionsView.ShowFooter = True
End Sub
Private orderCount As Integer = 0
Private Sub GridView_CustomSummaryCalculate(ByVal sender As Object, ByVal e As CustomSummaryEventArgs)
Dim view As GridView = TryCast(sender, GridView)
If e.IsTotalSummary Then
Select Case e.SummaryProcess
' Start calculation
Case CustomSummaryProcess.Start
orderCount = 0
' Consequent calculations
Case CustomSummaryProcess.Calculate
Dim today As Date = Date.Today
Dim orderDate As Date = Convert.ToDateTime(view.GetRowCellValue(e.RowHandle, view.Columns("OrderDate")))
Dim currentDayOfWeek As Integer = CInt(today.DayOfWeek)
Dim startOfWeek As Date = today.AddDays(-currentDayOfWeek + (If(currentDayOfWeek = 0, -6, 1))) ' Start on Monday
Dim endOfWeek As Date = startOfWeek.AddDays(6) ' End on Sunday
If orderDate.Date >= startOfWeek AndAlso orderDate <= endOfWeek Then
orderCount += 1
End If
' Final summary value
Case CustomSummaryProcess.Finalize
e.TotalValue = orderCount
End Select
End If
End Sub
Private Sub CreateTotalSummaries()
Dim total As New GridColumnSummaryItem() With {
.SummaryType = SummaryItemType.Count,
.DisplayFormat = "{0} orders"
}
' Add the total summary to the 'OrderID' column
colOrderID.Summary.Add(total)
Dim average As New GridColumnSummaryItem() With {
.SummaryType = SummaryItemType.Average,
.FieldName = "Freight",
.DisplayFormat = "Average: {0:#.#}"
}
' Add the average summary to the 'Freight' column
colFreight.Summary.Add(average)
Dim custom As New GridColumnSummaryItem() With {
.SummaryType = SummaryItemType.Custom,
.FieldName = "OrderDate",
.DisplayFormat = "This week: {0:n0} orders"
}
' Add the custom summary to the 'OrderDate' column
colOrderDate.Summary.Add(custom)
End Sub
End Class
End Namespace
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;
}
}
}
}
}
Imports System
Imports DevExpress.Data
Imports DevExpress.XtraBars.Ribbon
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Views.Grid
Namespace GridSummaries
Partial Public Class Form1
Inherits RibbonForm
Public Sub New()
InitializeComponent()
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
' Load data into the 'nwindDataSet.Orders' table
Me.ordersTableAdapter.Fill(Me.nwindDataSet.Orders)
' Create summaries
CreateGroupSummaries()
' Handle the event to calculate a custom summary
AddHandler gridView.CustomSummaryCalculate, AddressOf 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)
End Sub
Private Sub CreateGroupSummaries()
Dim total As New GridGroupSummaryItem() With {
.SummaryType = SummaryItemType.Count,
.DisplayFormat = "{0} orders"
}
Dim average As New GridGroupSummaryItem() With {
.SummaryType = SummaryItemType.Average,
.FieldName = "Freight",
.DisplayFormat = "Average: {0:#.#}",
.ShowInGroupColumnFooter = colFreight
}
Dim custom As New GridGroupSummaryItem() With {
.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 })
End Sub
Private orderCount As Integer = 0
Private Sub GridView_CustomSummaryCalculate(ByVal sender As Object, ByVal e As CustomSummaryEventArgs)
Dim view As GridView = TryCast(sender, GridView)
If e.IsGroupSummary Then
Select Case e.SummaryProcess
' Start calculation
Case CustomSummaryProcess.Start
orderCount = 0
' Consequent calculations
Case CustomSummaryProcess.Calculate
Dim today As Date = Date.Today
Dim orderDate As Date = Convert.ToDateTime(view.GetRowCellValue(e.RowHandle, view.Columns("OrderDate")))
Dim currentDayOfWeek As Integer = CInt(today.DayOfWeek)
Dim startOfWeek As Date = today.AddDays(-currentDayOfWeek + (If(currentDayOfWeek = 0, -6, 1))) ' Start on Monday
Dim endOfWeek As Date = startOfWeek.AddDays(6) ' End on Sunday
If orderDate.Date >= startOfWeek AndAlso orderDate <= endOfWeek Then
orderCount += 1
End If
' Final summary value
Case CustomSummaryProcess.Finalize
e.TotalValue = orderCount
End Select
End If
End Sub
End Class
End Namespace
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.
| API Member | Description |
|---|---|
| GridSummaryItem.SummaryValue | Gets the value of the summary item. |
| GridSummaryItem.GetDisplayText | 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;
|
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 \r\n sequence (for example, “Max: 1007.6400\r\n830 records”).
|
|
API Member
|
Description
| | --- | --- | |
|
Takes a row handle and a column as parameters and returns a DictionaryEntry object that allows you to obtain:
| |
GridView.GetGroupSummaryDisplayText
|
Return the value and display text of the specified group summary item displayed in the specified group row.
| |
GridView.GetGroupSummaryValues
|
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.
|
The following code snippet does the following:
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);
}
Imports System.Drawing
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Views.Grid
' Highlight a total summary
Private Sub GridView_CustomDrawFooterCell(ByVal sender As Object, ByVal e As FooterCellCustomDrawEventArgs)
If e.Column = colFreight Then
Dim summary As GridSummaryItem = e.Info.SummaryItem
Dim summaryValue As Double = Convert.ToDouble(summary.SummaryValue)
If summaryValue > 40 Then
e.Appearance.ForeColor = Color.Red
End If
End If
End Sub
' Highlight group rows based on a condition
Private Sub GridView_RowStyle(ByVal sender As Object, ByVal e As RowStyleEventArgs)
Dim view As GridView = TryCast(sender, GridView)
If view Is Nothing Then
Return
End If
If e.RowHandle >= 0 OrElse view.GroupCount = 0 Then
Return
End If
' Get all group summary values
Dim ht As Hashtable = view.GetGroupSummaryValues(e.RowHandle)
' Obtain the first group summary.
Dim groupSummaryItem As GridSummaryItem = view.GroupSummary(0)
' Obtain the group summary's value
Dim childRecordCount As Integer = Convert.ToInt32(ht(groupSummaryItem))
If childRecordCount > 30 Then
e.Appearance.BackColor = Color.FromArgb(70, Color.Yellow)
End If
End Sub
This example customizes the grid’s footer menu and calculates custom total 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:
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();
}
}
Private gridView1.CellValueChanged += AddressOf GridView1_CellValueChanged
Private Sub GridView1_CellValueChanged(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs)
Dim view As GridView = TryCast(sender, GridView)
If e.Column = colQuantity Then
view.UpdateTotalSummary()
End If
End Sub
See Also