Aggregate Functions
You can display aggregated information for the data in a column by adding aggregate functions to the AggregateFunctions collection of the column. The aggregate functions are included in Telerik.Windows.Data assembly.
Available Aggregate Functions
There are two main types of aggregate functions available which in turn serve as the base for the concrete implementations.
-
EnumerableAggregateFunction: Represents an AggregateFunction that uses aggregate extension methods provided in Enumerable.
CountFunction: Returns the number of all items in the column.
FirstFunction: Returns the first element in the column according to the current sorting.
LastFunction: Returns the last element in the column according to the current sorting.
-
EnumerableSelectorAggregateFunction: Represents an AggregateFunction that uses aggregate extension methods provided in Enumerable and uses its SourceField property as a member selector. If the SourceField property is not explicitly set, then the property specified for the DataMemberBinding of the column will be used.
AverageFunction: Returns the average of the values in the column.
MaxFunction: Returns the maximum value of the cell values in the column.
MinFunction: Returns the minimum value of the cell values in the column.
SumFunction: Returns the sum of all cell values in the column.
Check the Custom Aggregate Functions article to see how to implement custom aggregate functions by inheriting the EnumerableAggregateFunction
and EnumerableSelectorAggregateFunction
classes.
Adding an Aggregate Function
Aggregate functions can be added in xaml or in code behind. Examples 1 and 2 demonstrate both approaches. Note, that the RadGridView is populated with data as demonstrated in the Getting Started article.
Example 1: Populating the AggregateFunctions collection in xaml
<telerik:RadGridView x:Name="clubsGrid"
ItemsSource="{Binding Clubs}"
AutoGenerateColumns="False"
GroupRenderMode="Flat"
ShowColumnFooters="True">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Name}">
<telerik:GridViewDataColumn.AggregateFunctions>
<telerik:CountFunction Caption="Number of clubs: " />
<telerik:MaxFunction Caption="Maximum capacity: " SourceField="StadiumCapacity" />
</telerik:GridViewDataColumn.AggregateFunctions>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Established}"
Header="Est."
DataFormatString="{}{0:yyyy}"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding StadiumCapacity}"
Header="Stadium"
DataFormatString="{}{0:N0}"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
Example 2: Populating the AggregateFunctions collection in code
var countFunction = new CountFunction() { Caption = "Number of clubs: " };
var maxCapacityFunction = new MaxFunction() { Caption = "Maximum capacity: ", SourceField = "StadiumCapacity" };
var column = this.clubsGrid.Columns["Name"];
column.AggregateFunctions.Add(countFunction);
column.AggregateFunctions.Add(maxCapacityFunction);
Dim countFunction = New CountFunction() With {.Caption = "Number of clubs: "}
Dim maxCapacityFunction = New MaxFunction() With {
.Caption = "Maximum capacity: ",
.SourceField = "StadiumCapacity"
}
Dim column = Me.clubsGrid.Columns("Name")
column.AggregateFunctions.Add(countFunction)
column.AggregateFunctions.Add(maxCapacityFunction)
Figure 1: RadGridView with ShowColumnFooters set to True
You need to set the ShowColumnFooters and ShowGroupFooters properties to True in order to display aggregates under the columns and grouped rows respectively.
If omitted, the SourceField property of the aggregate functions is automatically set to the DataMemberBinding of the column.
RadGridView uses System.Linq to generate a proper Expression to do the calculation based on aggregate function defined and type of the bound data. Note that if an expression cannot be automatically generated, an exception will be thrown.
Autogenerated Columns
If your columns are auto-generated, you can subscribe to the AutoGeneratingColumn event and populate the AggregateFunctions collection as demonstrated in Example 3.
Example 3: Configuring column on AutoGeneratingColumn
private void clubsGrid_AutoGeneratingColumn(object sender, GridViewAutoGeneratingColumnEventArgs e)
{
var dataColumn = e.Column as GridViewBoundColumnBase;
if (dataColumn.DataMemberBinding.Path.Path == "Name")
{
var countFunction = new CountFunction() { Caption = "Number of clubs: " };
e.Column.AggregateFunctions.Add(countFunction);
}
}
Private Sub clubsGrid_AutoGeneratingColumn(ByVal sender As Object, ByVal e As GridViewAutoGeneratingColumnEventArgs)
Dim dataColumn = TryCast(e.Column, GridViewBoundColumnBase)
If dataColumn.DataMemberBinding.Path.Path = "Name" Then
Dim countFunction = New CountFunction() With {.Caption = "Number of clubs: "}
e.Column.AggregateFunctions.Add(countFunction)
End If
End Sub
ResultFormatString
You can specify a format string for the aggregate results by setting the ResultFormatString property of an aggregate function.
Example 4: Specifying ResultFormatString
<telerik:GridViewDataColumn.AggregateFunctions>
<telerik:SumFunction Caption="Total: $" ResultFormatString="{}{0:C2}"/>
</telerik:GridViewDataColumn.AggregateFunctions>
The code from Example 4 will display the aggregate results in the currency format with two digits after the decimal separator.
Update Results
If you need to recalculate the aggregate results, you can call the CalculateAggregates method of the control as shown in Example 5.
Example 5: Invoke CalculateAggregates() method
private void Button1_Click(object sender, RoutedEventArgs e)
{
this.radGridView.CalculateAggregates();
}
Private Sub Button1_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.radGridView.CalculateAggregates()
End Sub
Note that group aggregates will not be updated using this approach. Please check this troubleshooting article on how to refresh them.
Modify Displayed Aggregates
You can modify the default template of the displayed aggregates by setting the Footer property of the column as per your specific requirements.
Example 6: Overriding GridViewDataColumn.Footer
<telerik:GridViewDataColumn.Footer>
<StackPanel Orientation="Vertical"
Margin="0,10">
<TextBlock Text="Custom footer with aggregates:"
Margin="0,0,0,2" />
<telerik:AggregateResultsList ItemsSource="{Binding}"
VerticalAlignment="Center"
Grid.Column="4">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal"
VerticalAlignment="Center">
<TextBlock VerticalAlignment="Center"
Text="{Binding Caption}" />
<TextBlock VerticalAlignment="Center"
Text="{Binding FormattedValue}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</telerik:AggregateResultsList>
</StackPanel>
</telerik:GridViewDataColumn.Footer>
Figure 2: A GridViewDataColumn with a custom Footer
Note that the Footer's DataContext is of type AggregateResultsList.
Group Aggregates
Aggregate functions can also be defined per group. To find out more, take a look at the Group Aggregates article.
Default AggregateFunctions for a Custom Column
If you want to have a default aggregate function for the custom column which is not added in XAML, you need to add it after the initialization of the column. This can be done by overriding the EndInit method of FrameworkContentelement.
Example 7: Adding a default AggregateFunction
public class MyColumn : GridViewDataColumn
{
public MyColumn()
{
}
public override void EndInit()
{
this.AggregateFunctions.Add(new SumFunction());
base.EndInit();
}
}
Public Class MyColumn
Inherits GridViewDataColumn
Public Sub New()
End Sub
Public Overrides Sub EndInit()
Me.AggregateFunctions.Add(New SumFunction())
MyBase.EndInit()
End Sub
End Class