Back to Devexpress

Summary in Blazor TreeList

blazor-405038-components-treelist-data-shaping-summary.md

latest24.0 KB
Original Source

Summary in Blazor TreeList

  • Jul 07, 2025
  • 11 minutes to read

The Blazor TreeList component can calculate total summaries and display results in the footer. To add summaries, declare DxTreeListSummaryItem objects in the TotalSummary template and specify the following summary item settings:

Aggregate functionUse a summary’s SummaryType property to specify an aggregate function to calculate. DevExpress Blazor TreeList supports the following predefined functions: Sum, Min, Max, Avg, and Count.A data field that supplies values for calculationsSet the FieldName property to the name of a data field whose values are used to calculate the summary.

  • The Count function supports data fields of all types.
  • Min and Max functions support data fields whose values can be compared.
  • Avg and Sum functions require a numeric field.

A column that displays the summaryThe TreeList component displays total summaries in the TreeList footer under the column that supplies values for calculations. Use the FooterColumnName property to display the summary in another column.

The following example calculates total summaries for TreeList columns:

razor
@inject EmployeeTaskService EmployeeTaskService

<DxTreeList Data="TreeListData" KeyFieldName="Id" ParentKeyFieldName="ParentId">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
        <DxTreeListDataColumn FieldName="Status" Caption="Progress" DisplayFormat="p0" />
    </Columns>
    <TotalSummary>
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Count" FieldName="Name" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Min" FieldName="DueDate" ValueDisplayFormat="y" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Max" FieldName="DueDate" ValueDisplayFormat="y" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Avg" FieldName="Status" />
    </TotalSummary>
</DxTreeList>

@code {
    List<EmployeeTask> TreeListData { get; set; }

    protected override void OnInitialized() {
        TreeListData = EmployeeTaskService.GenerateData();
    }
}
csharp
public class EmployeeTask {
    public int Id { get; set; }
    public int ParentId { get; set; }
    public string Name { get; set; }
    public string EmployeeName { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime DueDate { get; set; }
    public int Progress { get; set; }
    public EmployeeTask() { }
    public EmployeeTask(
        int id,
        int parentId,
        string name,
        string employeeName,
        DateTime startDate,
        DateTime dueDate,
        int progress
        )
    {
        Id = id;
        ParentId = parentId;
        Name = name;
        EmployeeName = employeeName;
        StartDate = startDate;
        DueDate = dueDate;
        Progress = progress;
    }
}
csharp
public class EmployeeTaskService {
    public List<EmployeeTask> GenerateData() {
        return new List<EmployeeTask>() {
            new EmployeeTask(1, 0, "Simplify & Clarify Product Messaging", "John Heart", new DateTime(2018, 4, 3), new DateTime(2018, 4, 14), 14),
            new EmployeeTask(2, 1, "Prepare Financial Reports", "Samantha Bright", new DateTime(2018, 4, 3), new DateTime(2018, 4, 7), 17),
            new EmployeeTask(3, 1, "Prepare Marketing Plan", "Arthur Miller", new DateTime(2018, 4, 7), new DateTime(2018, 4, 14), 11),
            new EmployeeTask(4, 0, "Create Action Plan to Improve Customer Engagement", "Robert Reagan", new DateTime(2017, 8, 8), new DateTime(2018, 4, 8), 23),
            new EmployeeTask(5, 4, "Update Personnel Files", "Greta Sims", new DateTime(2017, 8, 8), new DateTime(2017, 10, 18), 100),
            new EmployeeTask(6, 4, "Review Health Insurance Options", "Brett Wade", new DateTime(2017, 9, 27), new DateTime(2017, 11, 10), 37),
            new EmployeeTask(7, 4, "Choose Between PPO and HMO Health Plan", "Sandra Johnson", new DateTime(2017, 12, 13), new DateTime(2018, 3, 23), 17),
            new EmployeeTask(8, 4, "Update Google Adwords Strategy", "Ed Holmes", new DateTime(2017, 8, 23), new DateTime(2017, 12, 23), 45),
            new EmployeeTask(9, 4, "Create New Brochure Design", "Barb Banks", new DateTime(2018, 1, 3), new DateTime(2018, 3, 14), 17),
            new EmployeeTask(10, 4, "Obtain Price Quote for New Brochure", "Kevin Carter", new DateTime(2018, 2, 1), new DateTime(2018, 3, 15), 18),
            new EmployeeTask(11, 4, "Brochure Design Review", "Cindy Stanwick", new DateTime(2017, 8, 22), new DateTime(2017, 10, 28), 4),
            new EmployeeTask(12, 4, "Review Website Redesign Strategy", "Sammy Hill", new DateTime(2017, 9, 16), new DateTime(2018, 3, 6), 73),
            new EmployeeTask(13, 4, "Roll Out New Website", "Davey Jones", new DateTime(2017, 11, 7), new DateTime(2018, 2, 6), 9),
            new EmployeeTask(14, 4, "Update Sales/Marketing Strategy", "Victor Norris", new DateTime(2017, 12, 13), new DateTime(2018, 4, 2), 5),
            new EmployeeTask(15, 4, "Update Sales/Revenue Report", "Mary Stern", new DateTime(2017, 12, 25), new DateTime(2018, 4, 2), 4),
            new EmployeeTask(16, 4, "Direct vs Online Sales Comparison Report", "Robin Cosworth", new DateTime(2018, 1, 2), new DateTime(2018, 3, 20), 14),
            new EmployeeTask(17, 4, "Review Sales Report and Approve Modifications", "Kelly Rodriguez", new DateTime(2017, 9, 4), new DateTime(2017, 10, 30), 8),
            new EmployeeTask(18, 4, "Update R&D Strategy", "James Anderson", new DateTime(2017, 11, 13), new DateTime(2017, 12, 4), 12),
            new EmployeeTask(19, 4, "Discuss Updated R&D Strategy", "Antony Remmen", new DateTime(2017, 10, 29), new DateTime(2017, 12, 31), 14),
            new EmployeeTask(20, 4, "Update QA Strategy", "Olivia Peyton", new DateTime(2017, 10, 31), new DateTime(2017, 11, 2), 18),
            new EmployeeTask(21, 4, "Schedule Training Events", "Taylor Riley", new DateTime(2017, 11, 19), new DateTime(2018, 4, 7), 21),
            new EmployeeTask(22, 4, "Approve Hiring of John Jeffers", "Amelia Harper", new DateTime(2018, 1, 7), new DateTime(2018, 4, 8), 10),
            new EmployeeTask(23, 0, "Increase Average Subscription Price", "Wally Hobbs", new DateTime(2017, 8, 9), new DateTime(2017, 9, 13), 96),
            new EmployeeTask(24, 23, "Update Non-Compete Agreements", "Brad Jameson", new DateTime(2017, 8, 9), new DateTime(2017, 9, 3), 96),
            new EmployeeTask(25, 23, "Update Employee Records with New NDA", "Karen Goodson", new DateTime(2017, 8, 23), new DateTime(2018, 9, 10), 100)
        };
    }
}
csharp
// ...
builder.Services.AddSingleton<EmployeeTaskService>();

Custom Summary

DevExpress TreeList for Blazor allows you to calculate total summaries based on custom logic. To create a custom summary, follow the steps below:

  1. Declare a DxTreeListSummaryItem object in the TotalSummary template.

  2. Set the SummaryType property to Custom.

  3. Handle the CustomSummary event to implement the summary calculation algorithm.

  4. (Optional). You may need to update summary values more often than the component does. For example, if you want to display summaries based on selected rows, you need to run calculations every time the selection changes. In such cases, call the RefreshSummary() method when necessary.

  5. (Optional). Specify the DisplayText property or handle the CustomizeSummaryDisplayText event to change the summary’s display text.

In the following example, a custom summary calculates the median for March Sales column values:

razor
@inject ISalesByRegionDataProvider SalesByRegionDataProvider

<DxTreeList Data="Data"
            KeyFieldName="ID"
            ParentKeyFieldName="RegionID"
            CustomSummary="TreeList_CustomSummary">
    <Columns>
        <DxTreeListDataColumn FieldName="Region" />
        <DxTreeListDataColumn FieldName="MarchSales" DisplayFormat="c0" />
        <DxTreeListDataColumn FieldName="MarchChange" DisplayFormat="p2" />
        <DxTreeListDataColumn FieldName="MarketShare" DisplayFormat="p0" />
    </Columns>
    <TotalSummary>
        <DxTreeListSummaryItem FieldName="MarchChange" DisplayText="Median: {0}"
                               SummaryType="TreeListSummaryItemType.Custom" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Avg" FieldName="MarchChange" />
    </TotalSummary>
</DxTreeList>

@code {
    List<SalesByRegion> Data { get; set; }

    protected override void OnInitialized() {
        Data = SalesByRegionDataProvider.GenerateData();
    }

    void TreeList_CustomSummary(TreeListCustomSummaryEventArgs e) {
        IEnumerable<SalesByRegion> OrderedData = Data.OrderBy(i => i.MarchChange);
        if (e.SummaryStage == TreeListCustomSummaryStage.Finalize) {
            int count = OrderedData.Count();
            if (count % 2 == 0) {
                var invoice1 = (SalesByRegion)OrderedData.Skip(count / 2 - 1).Take(1).First();
                var invoice2 = (SalesByRegion)OrderedData.Skip(count / 2).Take(1).First();
                e.TotalValue = (invoice1.MarchChange + invoice2.MarchChange) / 2;
            }
            else {
                var invoice = (SalesByRegion)OrderedData.Skip(count / 2).Take(1).First();
                e.TotalValue = invoice.MarchChange;
            }
        }
    }
}

Customize Summary Text

DevExpress Blazor TreeList constructs display text for a summary item based on the following predefined display formats:

<aggregate function>: <summary value>For the Count summary and summaries that are shown in a footer of the same column where the values are calculated.
Example: Max: 130<aggregate function> of <column caption>: <summary value>For summaries that are shown in a footer of another column.
Example: Max of Quantity: 130

You can modify summary text strings in the following ways.

Format Column Values and Summary Value in the Same Format

Use the EditSettings.DisplayFormat or DxTreeListDataColumn.DisplayFormat property to specify display format for column values. This format applies to the column summary value as well.

razor
<Columns>
    @* ... *@
    <DxTreeListDataColumn FieldName="Status" Caption="Progress" DisplayFormat="p0" />
</Columns>
<TotalSummary>
    <DxTreeListSummaryItem FieldName="Status" SummaryType="TreeListSummaryItemType.Avg" />
</TotalSummary>

Format Summary Value

Specify the ValueDisplayFormat property to format the calculated summary value (the <summary value> part). The summary value pattern can include static text mixed with an indexed placeholder ( {0} ) that corresponds to the calculated summary value.

razor
<DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Max" FieldName="DueDate" ValueDisplayFormat="y" />
<DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Avg" FieldName="Status" ValueDisplayFormat="~{0:p0}" />

Format Summary Text

A summary item’s DisplayText property allows you to specify a display text pattern for this summary. A display text string can include static text and placeholders for summary value and column caption.

razor
<DxTreeList Data="TreeListData" KeyFieldName="Id" ParentKeyFieldName="ParentId">
    <Columns>
        <DxTreeListDataColumn FieldName="Name" Caption="Task" />
        <DxTreeListDataColumn FieldName="EmployeeName" />
        <DxTreeListDataColumn FieldName="StartDate" />
        <DxTreeListDataColumn FieldName="DueDate" />
        <DxTreeListDataColumn FieldName="Status" Caption="Progress" DisplayFormat="p0" />
    </Columns>
    <TotalSummary>
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Max" FieldName="DueDate" DisplayText="Deadline: {0}" ValueDisplayFormat="y" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Avg" FieldName="Status" DisplayText="Average Progress: {0}" />
    </TotalSummary>
</DxTreeList>

To customize display text for an individual calculated summary value, handle the CustomizeSummaryDisplayText event. The TreeList event argument allows you to obtain information about the TreeList’s current state and add this information to a summary item’s display text.

Implement a Custom Template for Summary

You can specify DxTreeList.ColumnFooterTemplate and DxTreeListColumn.FooterTemplate properties to implement custom content for footers that display summaries. The following code sample applies italic formatting to all summary values:

razor
<ColumnFooterTemplate>
    @{
        var summaryItems = context.SummaryItems;
        if (summaryItems.Any()) {
            foreach (var i in summaryItems) {
                @context.TreeList.GetTotalSummaryLabel(i)
                <text>: </text>
                <i>@context.TreeList.GetTotalSummaryFormattedValue(i)</i> 

            }
        }
    }
</ColumnFooterTemplate>

Obtain Summary Values

DevExpress TreeList for Blazor implements methods that obtain total summary text and value. You can use these methods to display a summary in a template or in a separate control.

GetTotalSummaryDisplayTextGets a total summary item’s display text. Example: Avg of Unit Price: $26.22.GetTotalSummaryLabelReturns the name of a total summary‘s function name. Example: Avg of Unit Price.GetTotalSummaryFormattedValueGets a total summary item’s formatted value. Example: $26.22.GetTotalSummaryValueGets a total summary item’s value. Example: 26.21851972157772621809744.

Limitations

The following limitations apply:

This section contains a comprehensive summary-related API reference.

Show API Reference

DxTreeList API memberTypeDescription
TotalSummaryPropertyContains total summary items.
GetTotalSummaryItems()MethodReturns the collection of total summary items.
GetTotalSummaryValue(ITreeListSummaryItem)MethodGets a total summary item’s value.
GetTotalSummaryDisplayText(ITreeListSummaryItem)MethodGets a total summary item’s display text.
GetTotalSummaryLabel(ITreeListSummaryItem)MethodReturns the name of a total summary‘s function name.
GetTotalSummaryFormattedValue(ITreeListSummaryItem)MethodGets a total summary item’s formatted value.
RefreshSummary()MethodRefreshes all total summary values in the TreeList.
CustomSummaryEventAllows you to create custom summary items.
CustomizeSummaryDisplayTextEventAllows you to customize the summary display text.

Task-Based Examples

This section contains code samples that demonstrate TreeList summary functionality.

Remove the Default Summary Label

You can hide default summary labels in the following ways:

Calculate a Summary for Selected Rows

The following code sample calculates the sum of March Sales values of selected TreeList rows:

Run Demo: Custom Summary

razor
@inject ISalesByRegionDataProvider SalesByRegionDataProvider
<DxTreeList @ref="TreeList"
            Data="Data"
            KeyFieldName="ID"
            ParentKeyFieldName="RegionID"
            ShowAllRows="true"
            CustomSummary="TreeList_CustomSummary"
            CustomizeSummaryDisplayText="TreeList_CustomizeSummaryDisplayText"
            SelectedDataItemsChanged="TreeList_SelectedDataItemsChanged">
    <Columns>
        <DxTreeListSelectionColumn Width="50px" />
        <DxTreeListDataColumn FieldName="Region" Width="15%" />
        <DxTreeListDataColumn FieldName="MarchSales" DisplayFormat="c0" Width="25%" />
        <DxTreeListDataColumn FieldName="SeptemberSales" DisplayFormat="c0" Width="15%" />
        <DxTreeListDataColumn FieldName="MarchChange" DisplayFormat="p2" Width="15%" />
        <DxTreeListDataColumn FieldName="SeptemberChange" DisplayFormat="p2" Width="15%" />
        <DxTreeListDataColumn FieldName="MarketShare" DisplayFormat="p0" Width="15%" />
    </Columns>
    <TotalSummary>
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Count" FieldName="Region" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Sum" FieldName="MarchSales" />
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Custom" FieldName="MarchSales" Name="Custom" />
    </TotalSummary>
</DxTreeList>

@code {
    ITreeList TreeList { get; set; }
    object Data { get; set; }
    protected override void OnInitialized() {
        Data = SalesByRegionDataProvider.GenerateData();
    }
    void TreeList_CustomSummary(TreeListCustomSummaryEventArgs e) {
        switch(e.SummaryStage) {
            case TreeListCustomSummaryStage.Start:
                e.TotalValue = 0m;
                break;
            case TreeListCustomSummaryStage.Calculate:
                if(e.TreeList.IsDataItemSelected(e.DataItem))
                    e.TotalValue = (decimal)e.TotalValue + (decimal)e.GetRowValue("MarchSales");
                break;
        }
    }
    void TreeList_CustomizeSummaryDisplayText(TreeListCustomizeSummaryDisplayTextEventArgs e) {
        if(e.Item.Name == "Custom")
            e.DisplayText = string.Format("Sum of Selected ({0}): {1:c0}", e.TreeList.SelectedDataItems.Count, e.Value);
    }
    void TreeList_SelectedDataItemsChanged(IReadOnlyList<object> newSelection) {
        TreeList.RefreshSummary();
    }
}

Update Summary Values

If you implement a custom summary with a value that can change dynamically, call the RefreshSummary() method to update the TreeList’s summary values.

csharp
TreeList.RefreshSummary();

Run Demo: Custom Summary

Display a Summary Outside a TreeList

The TreeList component implements methods that obtain total summary text and value. See the following section for the list of available methods: Obtain Summary Values.

The following code snippet calls the GetTotalSummaryFormattedValue method to display a total summary value above the TreeList component.

razor
<h3>Total Sales: @SummaryText</h3>
<DxTreeList @ref="TreeList"
            Data="Data"
            KeyFieldName="ID"
            ParentKeyFieldName="RegionID"
            ShowAllRows="true">
    <Columns>
        <DxTreeListDataColumn FieldName="Region" />
        <DxTreeListDataColumn FieldName="MarchSales" DisplayFormat="c0" />
        <DxTreeListDataColumn FieldName="MarchChange" DisplayFormat="p2" />
        <DxTreeListDataColumn FieldName="MarketShare" DisplayFormat="p0" />
    </Columns>
    <TotalSummary>
        <DxTreeListSummaryItem SummaryType="TreeListSummaryItemType.Sum" FieldName="MarchSales" Visible="false" />
    </TotalSummary>
</DxTreeList>

@code {
    ITreeList TreeList { get; set; }
    object Data { get; set; }
    string SummaryText;

    protected override void OnInitialized() {
        Data = SalesByRegionDataProvider.GenerateData();
    }

    protected override void OnAfterRender(bool firstRender) {
        if(firstRender) {
            SummaryText = TreeList.GetTotalSummaryFormattedValue(TreeList.GetTotalSummaryItems()[0]);
            StateHasChanged();
        }
    }
}