Summaries

SfDataGrid provides support to display the concise information about the data objects using summaries. SfDataGrid provides below three different types of summary rows.

  • Table Summary – Used to display summary information of table either at top or bottom of SfDataGrid.
  • Group Summary – Used to display summary information of data objects in each group.
  • Caption Summary – Used to display summary information in the caption of the group.

Windows forms datagrid showing the types of summaries

Summary rows are represented by using GridSummaryRow and each GridSummaryRow hold summary information of columns in SummaryColumns property. The SummaryColumns contains the collection ofGridSummaryColumn which carries the name of column, format and its summary aggregate type.

Aggregate Types

The summary aggregate types can be specified by using GridSummaryColumn.SummaryType property and use the built-in function in GridSummaryColumn.Format.
The following are the list of predefined aggregate types and its built-in functions.

Aggregate Type

Built-in function

CountAggregate Count
Int32Aggregate Count, Max, Min, Average and Sum
DoubleAggregate Count, Max, Min, Average and Sum
Custom Used for custom summaries

Table Summary

The table summary calculates the summary value over all the records. SfDataGrid allows to add any number of table summary rows in top and bottom of SfDataGrid.

Adding Table Summary

Table summary row can be added in SfDataGrid by adding GridTableSummaryRow to SfDataGrid.TableSummaryRows collection.

Displaying Table Summary for Column

Summary information can be displayed in the column by setting GridSummaryRow.ShowSummaryInRow to false and defining summary columns. To calculate summary based on column you must specify the below properties,

  1. GridSummaryColumn.MappingName – MappingName of the column (Property name of data object).
  2. GridSummaryColumn.SummaryType – SfDataGrid provides different built-in summary calculation functions for various types.
  3. GridSummaryColumn.Format – Used to define format string for summary based on support function name’s in specified SummaryType.
    In the below code snippet, table summary is defined for OrderID column.
GridTableSummaryRow tableSummaryRow1 = new GridTableSummaryRow();
tableSummaryRow1.Name = "TableSummary";
tableSummaryRow1.ShowSummaryInRow = false;
tableSummaryRow1.Position = VerticalPosition.Bottom;

GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "TotalProduct";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "Total Product Count : {Sum:c}";
summaryColumn1.MappingName = "ProductName";

tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
Dim tableSummaryRow1 As New GridTableSummaryRow()
tableSummaryRow1.Name = "TableSummary"
tableSummaryRow1.ShowSummaryInRow = False
tableSummaryRow1.Position = VerticalPosition.Bottom

Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "TotalProduct"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "Total Product Count : {Sum:c}"
summaryColumn1.MappingName = "ProductName"

tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)

Windows forms datagrid showing table summary for column

Displaying Table Summary for Row

Summary information can be displayed in row by setting GridSummaryRow.ShowSummaryInRow to true and defining summary columns. GridSummaryRow.Title must set based on GridSummaryColumn.Name property to format summary columns values in row.

GridTableSummaryRow tableSummaryRow1 = new GridTableSummaryRow();
tableSummaryRow1.Name = "TableSummary";
tableSummaryRow1.ShowSummaryInRow = true;
tableSummaryRow1.Title = " Total Product Count: {TotalProduct}";
tableSummaryRow1.Position = VerticalPosition.Bottom;

GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "TotalProduct";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Count}";
summaryColumn1.MappingName = "ProductName";

tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
Dim tableSummaryRow1 As New GridTableSummaryRow()
tableSummaryRow1.Name = "TableSummary"
tableSummaryRow1.ShowSummaryInRow = True
tableSummaryRow1.Title = " Total Product Count: {ProductName}"
tableSummaryRow1.Position = VerticalPosition.Bottom

Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "TotalProduct"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Count}"
summaryColumn1.MappingName = "ProductName"

tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)

Windows form datagrid showing table summary for row

NOTE

GridSummaryRow.Title must be specified if GridSummaryRow.ShowSummaryInRow is enabled.

Positioning Table Summary Row

The Table summary can be positioned either at top or bottom of SfDataGrid by setting GridTableSummaryRow.Position property.

// Creates the TableSummaryRow.
GridTableSummaryRow tableSummaryRow1 = new GridTableSummaryRow();
tableSummaryRow1.Name = "TableSummary1";
tableSummaryRow1.ShowSummaryInRow = true;
tableSummaryRow1.Title = " Total Product Count: {ProductName}";
tableSummaryRow1.Position = VerticalPosition.Top;

GridTableSummaryRow tableSummaryRow2 = new GridTableSummaryRow();
tableSummaryRow2.Name = "TableSummary2";
tableSummaryRow2.ShowSummaryInRow = true;
tableSummaryRow2.Title = " Total Product Count: {ProductName}";
tableSummaryRow2.Position = VerticalPosition.Bottom;

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "TotalProduct";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Count:c}";
summaryColumn1.MappingName = "ProductName";

// Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1);
tableSummaryRow2.SummaryColumns.Add(summaryColumn1);

// Adds the GridTableSummaryRow in the TableSummaryRows collection.
this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow2);
' Creates the TableSummaryRow.
Dim tableSummaryRow1 As New GridTableSummaryRow()
tableSummaryRow1.Name = "TableSummary1"
tableSummaryRow1.ShowSummaryInRow = True
tableSummaryRow1.Title = " Total Product Count: {ProductName}"
tableSummaryRow1.Position = VerticalPosition.Top

Dim tableSummaryRow2 As New GridTableSummaryRow()
tableSummaryRow2.Name = "TableSummary2"
tableSummaryRow2.ShowSummaryInRow = True
tableSummaryRow2.Title = " Total Product Count: {ProductName}"
tableSummaryRow2.Position = VerticalPosition.Bottom

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "TotalProduct"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Count:c}"
summaryColumn1.MappingName = "ProductName"

' Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1)
tableSummaryRow2.SummaryColumns.Add(summaryColumn1)

' Adds the GridTableSummaryRow in the TableSummaryRows collection.
Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)
Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow2)

Windows form datagrid showing table summary row at top and bottom

Appearance

The appearance of the table summary can be customized by SfDataGrid.Style.TableSummaryRowStyle property. The TableSummaryRowStyle property contains all the settings that are needed for the table summary row appearance customization.

this.sfDataGrid1.Style.TableSummaryRowStyle.BackColor = Color.LightSkyBlue;
this.sfDataGrid1.Style.TableSummaryRowStyle.Borders.All = new GridBorder(Color.Black, GridBorderWeight.Medium);
this.sfDataGrid1.Style.TableSummaryRowStyle.Font = new GridFontInfo(new Font("Arial", 10f, FontStyle.Bold));
Me.sfDataGrid1.Style.TableSummaryRowStyle.BackColor = Color.LightSkyBlue
Me.sfDataGrid1.Style.TableSummaryRowStyle.Borders.All = New GridBorder(Color.Black, GridBorderWeight.Medium)
Me.sfDataGrid1.Style.TableSummaryRowStyle.Font = New GridFontInfo(New Font("Arial", 10f, FontStyle.Bold))

Table summary row appearance customization in windows form datagrid

Overriding Table Summary Renderer

GridTableSummaryCellRender is the cell renderer which renders the table summary row. The table summary row appearance and the summary value can be customized with the GridTableSummaryCellRender.

Creating Custom Renderer

The number format for numeric values displayed on GridTableSummaryRow can be applied by overriding the OnRender method in GridTableSummaryCellRenderer class.

public class CustomGridTableSummaryRenderer : GridTableSummaryCellRenderer
    {
        protected override void OnRender(Graphics paint, Rectangle cellRect, string cellValue,
            CellStyleInfo style, DataColumnBase column, RowColumnIndex rowColumnIndex)
        {
            if (string.IsNullOrEmpty(cellValue))
                return;
            // Creates new number format and apply it to summary value. 
            NumberFormatInfo format = new NumberFormatInfo();
            format.NumberDecimalDigits = 3;
            format.NumberDecimalSeparator = " * ";
            format.NumberGroupSeparator = ",";
            //Number format is applied to summary value.
            cellValue = Convert.ToDouble(double.Parse(cellValue, NumberStyles.Currency)).ToString("N", format);
            StringFormat stringFormat = new StringFormat();
            stringFormat.LineAlignment = StringAlignment.Center;
            stringFormat.Alignment = StringAlignment.Center;
            paint.DrawString(cellValue, style.Font.GetFont(), Brushes.Black, cellRect, stringFormat);
        }
    }
Public Class CustomGridTableSummaryRenderer
	  Inherits GridTableSummaryCellRenderer
		Protected Overrides Sub OnRender(ByVal paint As Graphics, ByVal cellRect As Rectangle, ByVal cellValue As String, ByVal style As CellStyleInfo, ByVal column As DataColumnBase, ByVal rowColumnIndex As RowColumnIndex)
			If String.IsNullOrEmpty(cellValue) Then
				Return
			End If
			' Creates new number format and apply it to summary value. 
			Dim format As New NumberFormatInfo()
			format.NumberDecimalDigits = 3
			format.NumberDecimalSeparator = " * "
			format.NumberGroupSeparator = ","
			'Number format is applied to summary value.
			cellValue = Convert.ToDouble(Double.Parse(cellValue, NumberStyles.Currency)).ToString("N", format)
			Dim stringFormat As New StringFormat()
			stringFormat.LineAlignment = StringAlignment.Center
			stringFormat.Alignment = StringAlignment.Center
			paint.DrawString(cellValue, style.Font.GetFont(), Brushes.Black, cellRect, stringFormat)
		End Sub
  End Class

Replacing Custom Renderer

The overridden custom table summary renderer can be replaced with default renderer by replacing the CustomGridTableSummaryRenderer to the TableSummary in the CellRenderers collection.

this.sfDataGrid1.CellRenderers.Remove("TableSummary");
this.sfDataGrid1.CellRenderers.Add("TableSummary", new CustomGridTableSummaryRenderer());
Me.sfDataGrid1.CellRenderers.Remove("TableSummary")
Me.sfDataGrid1.CellRenderers.Add("TableSummary", New CustomGridTableSummaryRenderer())

Custom table summary cell renderer in windows forms datagrid

Group Summary

Group summary values calculated based on the records in the group and the summary information will be displayed at the bottom of each group. The group summary row can be viewed by expanding the corresponding group header. SfDataGrid allows to add any number of group summary rows.

Adding Group Summary

The group summary rows can be added in SfDataGrid by adding the GridSummaryRow to SfDataGrid.GroupSummaryRows collection.

Displaying Group Summary for Column

Summary information can be displayed in the column by setting GridSummaryRow.ShowSummaryInRow to false and defining summary columns. To calculate summary based on column you should specify the below properties,

  1. GridSummaryColumn.MappingName – MappingName of the column (Property name of data object).
  2. GridSummaryColumn.SummaryType – SfDataGrid provides different built-in summary calculation functions for various types.
  3. GridSummaryColumn.Format – Used to define format string for summary based on support function name’s in specified SummaryType.
// Creates the GridSummaryRow.
GridSummaryRow groupSummaryRow1 = new GridSummaryRow();
groupSummaryRow1.Name = "GroupSummary";
groupSummaryRow1.ShowSummaryInRow = false;

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "UnitPrice";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "Total Price : {Sum:c}";
summaryColumn1.MappingName = "UnitPrice";

// Adds the GridSummaryColumn in SummaryColumns collection.
groupSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the summary row in the GroupSummaryRows collection.
this.sfDataGrid1.GroupSummaryRows.Add(groupSummaryRow1);
' Creates the GridSummaryRow.
Dim groupSummaryRow1 As New GridSummaryRow()
groupSummaryRow1.Name = "GroupSummary"
groupSummaryRow1.ShowSummaryInRow = False

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "UnitPrice"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "Total Price : {Sum:c}"
summaryColumn1.MappingName = "UnitPrice"

' Adds the GridSummaryColumn in SummaryColumns collection.
groupSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the summary row in the GroupSummaryRows collection.
Me.sfDataGrid1.GroupSummaryRows.Add(groupSummaryRow1)

Windows forms datagrid showing group summary

Displaying Group Summary for Row

Summary information can be displayed in row by setting GridSummaryRow.ShowSummaryInRow to true and defining summary columns. GridSummaryRow.Title should be defined based on GridSummaryColumn.Name property to format summary columns values in row.

// Creates the GridSummaryRow.
GridSummaryRow groupSummaryRow1 = new GridSummaryRow();
groupSummaryRow1.Name = "GroupSummary";
groupSummaryRow1.ShowSummaryInRow = true;
groupSummaryRow1.Title = "Total Price $: { UnitPrice }";

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "UnitPrice";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Sum:c}";
summaryColumn1.MappingName = " UnitPrice ";

// Adds the GridSummaryColumn in SummaryColumns collection.
groupSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the summary row in the GroupSummaryRows collection.
this.sfDataGrid1.GroupSummaryRows.Add(groupSummaryRow1);
' Creates the GridSummaryRow.
Dim groupSummaryRow1 As New GridSummaryRow()
groupSummaryRow1.Name = "GroupSummary"
groupSummaryRow1.ShowSummaryInRow = True
groupSummaryRow1.Title = "Total Price $: { UnitPrice }"

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "UnitPrice"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Sum:c}"
summaryColumn1.MappingName = " UnitPrice "

' Adds the GridSummaryColumn in SummaryColumns collection.
groupSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the summary row in the GroupSummaryRows collection.
Me.sfDataGrid1.GroupSummaryRows.Add(groupSummaryRow1)

Windows forms datagrid showing display group summary for row

NOTE

GridSummaryRow.Title must be specified if GridSummaryRow.ShowSummaryInRow is enabled.

Appearance

The appearance of the group summary can be customized by SfDataGrid.Style.GroupSummaryRowStyle property. The GroupSummaryRowStyle property contains all the settings that are needed for the group summary row appearance customization.

this.sfDataGrid1.Style.GroupSummaryRowStyle.BackColor = Color.LightSkyBlue;
this.sfDataGrid1.Style.GroupSummaryRowStyle.Font = new GridFontInfo(new Font("Arial", 10f, FontStyle.Bold));
Me.sfDataGrid1.Style.GroupSummaryRowStyle.BackColor = Color.LightSkyBlue
Me.sfDataGrid1.Style.GroupSummaryRowStyle.Font = New GridFontInfo(New Font("Arial", 10f, FontStyle.Bold))

Group summary row Appearance customization in windows forms datagrid

Overriding Group Summary Renderer

GridGroupSummaryCellRenderer is the cell renderer which renders the group summary row. The group summary row appearance and the summary value can be customized with the GridGroupSummaryCellRender.

Creating Custom Renderer

The number format for numeric values displayed on group summary row can be applied by overriding the OnRender method in GridGroupSummaryCellRenderer class.

public class CustomGridGroupSummaryRenderer : GridGroupSummaryCellRenderer
    {
        protected override void OnRender(Graphics paint, Rectangle cellRect, string cellValue,
            CellStyleInfo style, DataColumnBase column, RowColumnIndex rowColumnIndex)
        {
            if (string.IsNullOrEmpty(cellValue))
                return;
            // Creates new number format and apply it to summary value. 
            NumberFormatInfo format = new NumberFormatInfo();
            format.NumberDecimalDigits = 3;
            format.NumberDecimalSeparator = "*";
            format.NumberGroupSeparator = ",";
            //Number format is applied to summary value.
            cellValue = Convert.ToDouble(double.Parse(cellValue, NumberStyles.Currency)).ToString("N", format);
            StringFormat stringFormat = new StringFormat();
            stringFormat.LineAlignment = StringAlignment.Center;
            stringFormat.Alignment = StringAlignment.Center;
            paint.DrawString(cellValue, style.Font.GetFont(), Brushes.Black, cellRect, stringFormat);
        }
    }
Public Class CustomGridGroupSummaryRenderer
	Inherits GridGroupSummaryCellRenderer
		Protected Overrides Sub OnRender(ByVal paint As Graphics, ByVal cellRect As Rectangle, ByVal cellValue As String, ByVal style As CellStyleInfo, ByVal column As DataColumnBase, ByVal rowColumnIndex As RowColumnIndex)
			If String.IsNullOrEmpty(cellValue) Then
				Return
			End If
			' Creates new number format and apply it to summary value. 
			Dim format As New NumberFormatInfo()
			format.NumberDecimalDigits = 3
			format.NumberDecimalSeparator = "*"
			format.NumberGroupSeparator = ","
			'Number format is applied to summary value.
			cellValue = Convert.ToDouble(Double.Parse(cellValue, NumberStyles.Currency)).ToString("N", format)
			Dim stringFormat As New StringFormat()
			stringFormat.LineAlignment = StringAlignment.Center
			stringFormat.Alignment = StringAlignment.Center
			paint.DrawString(cellValue, style.Font.GetFont(), Brushes.Black, cellRect, stringFormat)
		End Sub
End Class

Replacing Custom Renderer

The overridden custom group summary renderer can be replaced with default renderer by replacing the CustomGridGroupSummaryRenderer to the GroupSummary in the CellRenderers collection.

this.sfDataGrid1.CellRenderers.Remove("GroupSummary");
this.sfDataGrid1.CellRenderers.Add("GroupSummary", new CustomGridGroupSummaryRenderer());
Me.sfDataGrid1.CellRenderers.Remove("GroupSummary")
Me.sfDataGrid1.CellRenderers.Add("GroupSummary", New CustomGridGroupSummaryRenderer())

Custom group summary cell renderer in windows forms datagrid

Caption Summary

SfDataGrid provides built-in support for caption summary. The caption summary value calculated based on the records in a group and the summary information will be displayed in the caption of group.
Below screen shot shows the built-in caption summary of Group.

Windows forms datagrid showing group caption summary

Formatting Built-in Caption Summary

The group caption text can be formatted using the SfDataGrid.GroupCaptionTextFormat property.

The default group caption format is {ColumnName}: {Key} - {ItemsCount} Items.

  • ColumnName - Displays the name of the column currently grouped.
  • Key - Displays the key value of group.
  • ItemsCount - Displays the number of items in group.
    The group caption format can be changed to Key and ItemsCount alone by setting GroupCaptionTextFormat as below,
this.sfDataGrid1.GroupCaptionTextFormat = "{Key} : {ItemsCount}";
Me.sfDataGrid1.GroupCaptionTextFormat = "{Key} : {ItemsCount}"

Custom group summary format in windows forms datagrid

Displaying Caption Summary for Column

Summary information can be displayed in the column by setting GridSummaryRow.ShowSummaryInRow to false and defining summary columns. To calculate summary based on column the below properties must be specified,

  1. GridSummaryColumn.MappingName – MappingName of the column (Property name of data object).
  2. GridSummaryColumn.SummaryType – SfDataGrid provides different built-in summary calculation functions for various types.
  3. GridSummaryColumn.Format – Used to define format string for summary based on support function name’s in specified SummaryType.
// Creates the GridSummaryRow.
GridSummaryRow captionSummaryRow = new GridSummaryRow();
captionSummaryRow.Name = "CaptionSummary";
captionSummaryRow.ShowSummaryInRow = false;

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "Column1";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Sum:c}";
summaryColumn1.MappingName = "UnitPrice";

GridSummaryColumn summaryColumn2 = new GridSummaryColumn();
summaryColumn2.Name = "Column2";
summaryColumn2.SummaryType = SummaryType.Int32Aggregate;
summaryColumn2.Format = "{Count}";
summaryColumn2.MappingName = "OrderID";

// Adds the summary column in the SummaryColumns collection.
captionSummaryRow.SummaryColumns.Add(summaryColumn1);
captionSummaryRow.SummaryColumns.Add(summaryColumn2);

// Initializes the caption summary row.
this.sfDataGrid1.CaptionSummaryRow = captionSummaryRow;
' Creates the GridSummaryRow.
Dim captionSummaryRow As New GridSummaryRow()
captionSummaryRow.Name = "CaptionSummary"
captionSummaryRow.ShowSummaryInRow = False

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "Column1"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Sum:c}"
summaryColumn1.MappingName = "UnitPrice"

Dim summaryColumn2 As New GridSummaryColumn()
summaryColumn2.Name = "Column2"
summaryColumn2.SummaryType = SummaryType.Int32Aggregate
summaryColumn2.Format = "{Count}"
summaryColumn2.MappingName = "OrderID"

' Adds the summary column in the SummaryColumns collection.
captionSummaryRow.SummaryColumns.Add(summaryColumn1)
captionSummaryRow.SummaryColumns.Add(summaryColumn2)

' Initializes the caption summary row.
Me.sfDataGrid1.CaptionSummaryRow = captionSummaryRow

Windows forms datagrid showing group caption summary for column

Displaying Caption Summary for Row

Summary information can be displayed in row by setting GridSummaryRow.ShowSummaryInRow to true and defining summary columns. GridSummaryRow.Title based on GridSummaryColumn.Name property must be defined to format the summary columns values in row.

// Creates the GridSummaryRow.
GridSummaryRow captionSummaryRow = new GridSummaryRow();
captionSummaryRow.Name = "CaptionSummary";
captionSummaryRow.ShowSummaryInRow = true;
captionSummaryRow.Title = " Total Quantity of {Key} : {Quantity}";

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "Quantity";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Sum:c}";
summaryColumn1.MappingName = "Quantity";

// Adds the summary column in the SummaryColumns collection.
captionSummaryRow.SummaryColumns.Add(summaryColumn1);

// Initializes the caption summary row.
this.sfDataGrid1.CaptionSummaryRow = captionSummaryRow;
' Creates the GridSummaryRow.
Dim captionSummaryRow As New GridSummaryRow()
captionSummaryRow.Name = "CaptionSummary"
captionSummaryRow.ShowSummaryInRow = True
captionSummaryRow.Title = " Total Quantity of {Key} : {Quantity}"

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "Quantity"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Sum:c}"
summaryColumn1.MappingName = "Quantity"

' Adds the summary column in the SummaryColumns collection.
captionSummaryRow.SummaryColumns.Add(summaryColumn1)

' Initializes the caption summary row.
Me.sfDataGrid1.CaptionSummaryRow = captionSummaryRow

Windows forms datagrid showing group caption summary for row

Appearance

The appearance of the caption summary can be customized by SfDataGrid.Style.CaptionSummaryRowStyle property. The CaptionSummaryRowStyle property contains all the settings that are needed for the caption summary row appearance customization.

this.sfDataGrid1.Style.CaptionSummaryRowStyle.BackColor = Color.LightSkyBlue;
this.sfDataGrid1.Style.CaptionSummaryRowStyle.Font = new GridFontInfo(new Font("Arial", 10f, FontStyle.Bold));
Me.sfDataGrid1.Style.CaptionSummaryRowStyle.BackColor = Color.LightSkyBlue
Me.sfDataGrid1.Style.CaptionSummaryRowStyle.Font = New GridFontInfo(New Font("Arial", 10f, FontStyle.Bold))

Group caption appearance customization in windows forms datagrid

Overriding Caption Summary Renderer

GridCaptionSummaryCellRenderer is the cell renderer which renders the caption summary row. The caption summary row appearance and the summary value can be customized with the GridCaptionSummaryCellRender.

Creating Custom Renderer

Number format for numeric values displayed on caption summary row can be applied by overriding the OnRender method in GridCaptionSummaryCellRenderer class.

public class CustomGridCaptionSummaryRenderer : GridCaptionSummaryCellRenderer
    {
        protected override void OnRender(Graphics paint, Rectangle cellRect, string cellValue,
         CellStyleInfo style, DataColumnBase column, RowColumnIndex rowColumnIndex)
        {
            if (string.IsNullOrEmpty(cellValue))
                return;
            StringFormat stringFormat = new StringFormat();
            stringFormat.LineAlignment = StringAlignment.Center;
            stringFormat.Alignment = StringAlignment.Center;
            if (column.GridColumn.MappingName == "UnitPrice")
            {
                // Creates new number format and apply it to summary value. 
                NumberFormatInfo format = new NumberFormatInfo();
                format.NumberDecimalDigits = 3;
                format.NumberDecimalSeparator = "*";
                format.NumberGroupSeparator = ",";
                //Number format is applied to summary value.
                cellValue = Convert.ToDouble(double.Parse(cellValue, NumberStyles.Currency)).ToString("N", format);
            }
            paint.DrawString(cellValue, style.Font.GetFont(), Brushes.Black, cellRect, stringFormat);
        }
    }
Public Class CustomGridCaptionSummaryRenderer
	Inherits GridCaptionSummaryCellRenderer
		Protected Overrides Sub OnRender(ByVal paint As Graphics, ByVal cellRect As Rectangle, ByVal cellValue As String, ByVal style As CellStyleInfo, ByVal column As DataColumnBase, ByVal rowColumnIndex As RowColumnIndex)
			If String.IsNullOrEmpty(cellValue) Then
				Return
			End If
			Dim stringFormat As New StringFormat()
			stringFormat.LineAlignment = StringAlignment.Center
			stringFormat.Alignment = StringAlignment.Center
			If column.GridColumn.MappingName = "UnitPrice" Then
				' Creates new number format and apply it to summary value. 
				Dim format As New NumberFormatInfo()
				format.NumberDecimalDigits = 3
				format.NumberDecimalSeparator = "*"
				format.NumberGroupSeparator = ","
				'Number format is applied to summary value.
				cellValue = Convert.ToDouble(Double.Parse(cellValue, NumberStyles.Currency)).ToString("N", format)
			End If
			paint.DrawString(cellValue, style.Font.GetFont(), Brushes.Black, cellRect, stringFormat)
		End Sub
End Class

Replacing Custom Renderer

The overridden custom caption summary renderer can be replaced with default renderer by replacing the CustomGridCaptionSummaryRenderer to the CaptionSummary in the CellRenderers collection.

this.sfDataGrid1.CellRenderers.Remove("CaptionSummary");
this.sfDataGrid1.CellRenderers.Add("CaptionSummary", new CustomGridCaptionSummaryRenderer());
Me.sfDataGrid1.CellRenderers.Remove("CaptionSummary")
Me.sfDataGrid1.CellRenderers.Add("CaptionSummary", New CustomGridCaptionSummaryRenderer())

Custom group caption summary cell renderer in windows forms datagrid

On-demand summary calculation for group and caption summary

You can calculate the caption and group summaries on-demand by setting the sfDataGrid.SummaryCalculationMode property to ‘CalculationMode.OnDemandCaptionSummary’ or ‘CalculationMode.OnDemandGroupSummary’. You can set this property when loading more number of summary columns on summary row or more number of group summaries to improve loading performance. The on-demand summary calculation calculates summaries for the summary rows that are visible, and summaries for other rows will be calculated only when it comes into view.

this.sfDataGrid.SummaryCalculationMode = CalculationMode.OnDemandCaptionSummary | CalculationMode.OnDemandGroupSummary;
Me.sfDataGrid.SummaryCalculationMode = CalculationMode.OnDemandCaptionSummary Or CalculationMode.OnDemandGroupSummary

Formatting Summary

In the below sections, formatting is explained using table summary. In the same way, group and caption summaries can also be formatted.

Defining Summary Function

In the below code snippet Format property is defined to display sum of UnitPrice by specifying the function name inside curly braces.

NOTE

DoubleAggregate is used as SummaryType which has Count, Max, Min, Average and Sum functions.

// Creates the TableSummaryRow.
GridTableSummaryRow tableSummaryRow1 = new GridTableSummaryRow();
tableSummaryRow1.Name = "TableSummary";
tableSummaryRow1.ShowSummaryInRow = false;
tableSummaryRow1.Position = TableSummaryRowPosition.Bottom;

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "UnitPrice";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Sum}";
summaryColumn1.MappingName = " UnitPrice ";

// Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the GridTableSummaryRow in the TableSummaryRows collection.
this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
' Creates the TableSummaryRow.
Dim tableSummaryRow1 As New GridTableSummaryRow()
tableSummaryRow1.Name = "TableSummary"
tableSummaryRow1.ShowSummaryInRow = False
tableSummaryRow1.Position = TableSummaryRowPosition.Bottom

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "UnitPrice"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Sum}"
summaryColumn1.MappingName = " UnitPrice "

' Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the GridTableSummaryRow in the TableSummaryRows collection.
Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)

Windows forms datagrid showing formatting summaries

Formatting Summary Value

The summary value can be formatted by setting the appropriate format after the aggregate function followed by colon(:) in GridSummaryColumn.Format property.
In the below code snippet UnitPrice column summary is formatted using c format specifier. Refer here to know about how to set different format.

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "UnitPrice";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Sum:c}";
summaryColumn1.MappingName = " UnitPrice ";

// Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the GridTableSummaryRow in the TableSummaryRows collection.
this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "UnitPrice"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Sum:c}"
summaryColumn1.MappingName = " UnitPrice "

' Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the GridTableSummaryRow in the TableSummaryRows collection.
Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)

Windows forms datagrid showing formatting summary value

Displaying Additional Content in Summary

Additional content can be appended with summary value using GridSummaryColumn.Format property.

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "TotalPrice";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "Total Price : {Sum:c}";
summaryColumn1.MappingName = "UnitPrice";

// Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the GridTableSummaryRow in the TableSummaryRows collection.
this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "TotalPrice"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "Total Price : {Sum:c}"
summaryColumn1.MappingName = "UnitPrice"

' Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the GridTableSummaryRow in the TableSummaryRows collection.
Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)

Windows forms datagrid showing display additional content with summary value

Formatting Summary for Row

The summary value for row can be formatted by using GridSummaryRow.Title when ShowSummaryInRow set to true.

// Creates the TableSummaryRow.
GridTableSummaryRow tableSummaryRow1 = new GridTableSummaryRow();
tableSummaryRow1.Name = "TableSummary";
tableSummaryRow1.ShowSummaryInRow = true;
tableSummaryRow1.Title = " Total Unit Price: {UnitPrice} ";
tableSummaryRow1.Position = TableSummaryRowPosition.Top;

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "TotalPrice";
summaryColumn1.SummaryType = SummaryType.DoubleAggregate;
summaryColumn1.Format = "{Sum:c}";
summaryColumn1.MappingName = " UnitPrice ";

// Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the GridTableSummaryRow in the TableSummaryRows collection.
this.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1);
' Creates the TableSummaryRow.
Dim tableSummaryRow1 As New GridTableSummaryRow()
tableSummaryRow1.Name = "TableSummary"
tableSummaryRow1.ShowSummaryInRow = True
tableSummaryRow1.Title = " Total Unit Price: {UnitPrice} "
tableSummaryRow1.Position = TableSummaryRowPosition.Top

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "TotalPrice"
summaryColumn1.SummaryType = SummaryType.DoubleAggregate
summaryColumn1.Format = "{Sum:c}"
summaryColumn1.MappingName = " UnitPrice "

' Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the GridTableSummaryRow in the TableSummaryRows collection.
Me.sfDataGrid1.TableSummaryRows.Add(tableSummaryRow1)

Windows forms datagrid showing formatting summary for row

Custom Summaries

SfDataGrid allows to implement own aggregate functions, when the built-in aggregate functions don’t meet the requirement.
The summary values can be calculated based on custom logic using GridSummaryColumn.CustomAggregate property.

Implementing Custom Aggregate

1) Create custom aggregate class by deriving from ISummaryAggregate interface.

2) In the CalculateAggregateFunc method, the summary must be calculated and assign it to the property.
In the below code snippet, the Standard Deviation is calculated for quantity of products.

public class CustomAggregate : ISummaryAggregate
{
    public CustomAggregate()
    {
    }
    public double StdDev { get; set; }
    Action<IEnumerable, string, PropertyDescriptor> ISummaryAggregate.CalculateAggregateFunc()
    {
        return (items, property, pd) =>
        {
            var enumerableItems = items as IEnumerable<SalesByYear>;
            if (pd.Name == "StdDev")
            {
                this.StdDev = enumerableItems.StdDev<SalesByYear>(q => q.Total);
            }
        };
    }
}

public static class LinqExtensions
{
    public static double StdDev<T>(this IEnumerable<T> values, Func<T, double?> selector)
    {
        double result = 0;
        var count = values.Count();
        if (count > 0)
        {
            double? avg = values.Average(selector);
            double sum = values.Select(selector).Sum(d =>
            {
                if (d.HasValue)
                {
                    return Math.Pow(d.Value - avg.Value, 2);
                }
                return 0.0;
            });
            result = Math.Sqrt((sum) / (count - 1));
        }
        return result;
    }
}
Public Class CustomAggregate
	Implements ISummaryAggregate
	Public Sub New()
	End Sub
	Public Property StdDev() As Double

	Private Function CalculateAggregateFunc() As Action(Of IEnumerable, String, PropertyDescriptor) Implements ISummaryAggregate.CalculateAggregateFunc
		Return Sub(items, property, pd)
			Dim enumerableItems = TryCast(items, IEnumerable(Of SalesByYear))
			If pd.Name = "StdDev" Then
				Me.StdDev = enumerableItems.StdDev(Of SalesByYear)(Function(q) q.Total)
			End If
		End Sub
	End Function
End Class

Public Module LinqExtensions
	<System.Runtime.CompilerServices.Extension> _
	Public Function StdDev(Of T)(ByVal values As IEnumerable(Of T), ByVal selector As Func(Of T, Double?)) As Double
		Dim result As Double = 0
		Dim count = values.Count()
		If count > 0 Then
			Dim avg? As Double = values.Average(selector)

			Dim sum As Double = values.Select(selector).Sum(Function(d)
				If d.HasValue Then
					Return Math.Pow(d.Value - avg.Value, 2)
				End If
				Return 0.0
			End Function)
			result = Math.Sqrt((sum) / (count - 1))
		End If
		Return result
	End Function
End Module

3) Assign the custom aggregate to GridSummaryColumn.CustomAggregate property and set the SummaryType as Custom. GridSummaryColumn.Format property is defined based on property name in custom aggregate StdDev.

// Creates the TableSummaryRow.
GridTableSummaryRow tableSummaryRow1 = new GridTableSummaryRow();
tableSummaryRow1.Name = "TableSummary";
tableSummaryRow1.ShowSummaryInRow = true;
tableSummaryRow1.Title = "Standard Deviation for Total Sales : {TotalSales}";
tableSummaryRow1.Position = TableSummaryRowPosition.Top;

// Creates the GridSummaryColumn.
GridSummaryColumn summaryColumn1 = new GridSummaryColumn();
summaryColumn1.Name = "TotalSales";
summaryColumn1.SummaryType = SummaryType.Custom;
// Initialize the CustomAggregate.
summaryColumn1.CustomAggregate = new CustomAggregate();
summaryColumn1.Format = "{StdDev}";

// Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1);

// Adds the GridTableSummaryRow in the TableSummaryRows collection.
this.sfDataGrid.TableSummaryRows.Add(tableSummaryRow1);
' Creates the TableSummaryRow.
Dim tableSummaryRow1 As New GridTableSummaryRow()
tableSummaryRow1.Name = "TableSummary"
tableSummaryRow1.ShowSummaryInRow = True
tableSummaryRow1.Title = "Standard Deviation for Total Sales : {TotalSales}"
tableSummaryRow1.Position = TableSummaryRowPosition.Top

' Creates the GridSummaryColumn.
Dim summaryColumn1 As New GridSummaryColumn()
summaryColumn1.Name = "TotalSales"
summaryColumn1.SummaryType = SummaryType.Custom
' Initialize the CustomAggregate.
summaryColumn1.CustomAggregate = New CustomAggregate()
summaryColumn1.Format = "{StdDev}"

' Adds the GridSummaryColumn in the SummaryColumns collection.
tableSummaryRow1.SummaryColumns.Add(summaryColumn1)

' Adds the GridTableSummaryRow in the TableSummaryRows collection.
Me.sfDataGrid.TableSummaryRows.Add(tableSummaryRow1)

Windows forms datagrid showing custom summary

You can download the custom summaries demo here.