Skip to content

Summary. Customization#

Flexible TreeView allows you to customize summaries either at design-time or at run-time.

Design-time customization#

To customize summaries at design-time, use the Summaries treeview property's designer in Visual Studio.

Run-time customization#

You can customize summaries at run-time using the summary's context menu. To display it, right-click on the summary or on the summary area's empty space. To prevent the context menu from showing at run-time, disable the Options.Summary.ShowContextMenu treeview property (enabled by default).

The summary's context menu allows you to modify the summary's settings or delete the summary.

Flexible TreeView supports run-time summary customization through a customization dialog, accessible from the summary context menu. To access it, select the Summary editor menu item.

To prevent the customization dialog from showing, disable the Options.Summary.AllowCustomize treeview property (enabled by default).

Events#

For run-time summary customization, Flexible TreeView provides these events:

  • SummaryCreated - Raised when a new summary is added either from the context menu or customization dialog. Use this event to dynamically initialize a new summary.
  • FormatSummaryValue - Raised when the treeview needs to display the summary value. Here you can dynamically format any summary value.

Run-time summary auto-creation#

Each summary is bound to a node control to obtain data for aggregation. To add a new summary from the context menu or customization dialog at run-time, the treeview needs to know which node control to bind the new summary to. To inform the treeview of these node controls, populate the Summaries.DefaultNodeControls treeview property with the desired node controls for each column as shown below:

// Every new summary created in the 'priceColumn' column will be bound to the textboxNodeControl node control.
tree.Summaries.DefaultNodeControls.Add(priceColumn, textboxNodeControl);

// Every new summary created in the treeview without columns will be bound to the numericNodeControl node control.
tree.Summaries.DefaultNodeControls.Add(null, numericNodeControl);
' Every new summary created in the 'priceColumn' column will be bound to the textboxNodeControl node control.
tree.Summaries.DefaultNodeControls.Add(priceColumn, textboxNodeControl)

' Every new summary created in the treeview without columns will be bound to the numericNodeControl node control.
tree.Summaries.DefaultNodeControls.Add(Nothing, numericNodeControl)

Note

You can assign only one node control for each column or for the null value (in a treeview without columns). Users cannot add a summary if there is no defined node control for a target column.

The treeview raises the SummaryCreated event for each newly created summary, where you can initialize it like this:

void tree_SummaryCreated(FlexibleTreeView treeview, SummaryCreatedEventArgs args)
{
    if (args.SummaryItem.Operation == eSummaryOperation.Sum)
    {
        args.SummaryItem.NodeControl = numericNodeControl;
        args.SummaryItem.Stretch = true;
    }
}
Private Sub tree_SummaryCreated(treeview As FlexibleTreeView, args As SummaryCreatedEventArgs)
    If args.SummaryItem.Operation = eSummaryOperation.Sum Then
        args.SummaryItem.NodeControl = numericNodeControl
        args.SummaryItem.Stretch = True
    End If
End Sub

Dependent summaries#

Typically, each summary item calculates its value using a specified node control that retrieves values from treeview nodes. However, Flexible TreeView also allows you to create a summary item whose value partially or completely depends on other summaries' values.

To create such a summary, implement a custom data provider class that retrieves the required data from other summaries, as shown below:

class DependentDataProvider : SummaryDataProviderBase
{
    public override eSummaryOperation Operation
    {
        get { return eSummaryOperation.Custom; }
    }

    public DependentDataProvider() : base("HalfValue", "Half")
    {
    }

    public override bool IsNodeControlSupported(NodeControl control)
    {
        return true;
    }

    public override object GetSummaryValue(Node node, ISummaryItem summary)
    {
        // TODO: Retrieve the summary values that this summary depends on...
    }
}
Class DependentDataProvider
    Inherits SummaryDataProviderBase
    Public Overrides ReadOnly Property Operation() As eSummaryOperation
        Get
            Return eSummaryOperation.Custom
        End Get
    End Property

    Public Sub New()
        MyBase.New("HalfValue", "Half")
    End Sub

    Public Overrides Function IsNodeControlSupported(control As NodeControl) As Boolean
        Return True
    End Function

    Public Overrides Function GetSummaryValue(node As Node, summary As ISummaryItem) As Object
        ' TODO: Retrieve the summary values that this summary depends on...
    End Function
End Class

Override the GetSummaryValue method to calculate and return the summary value, including accessing other summaries' values. To access other summaries, use the node.Treeview.Summaries property directly.

For example, let's say we added two treeview-level summaries to the Summaries.Treeview collection. One summary calculates the average value of the specified node control, while the second summary returns half of the first summary's value. Here's how the GetSummaryValue method should look:

public override object GetSummaryValue(Node node, ISummaryItem summary)
{
    // Retrieve first treeview-level summary by its index.
    TreeviewSummaryItem firstSummary = node.Treeview.Summaries.Treeview[0];
    // Retrieve first summary's value.
    decimal firstValue = (decimal)firstSummary.DataProvider.GetSummaryValue(node, firstSummary);

    // Calculate this summary value based on the other summary.
    decimal result = firstValue / 2;
    return result;
}
Public Overrides Function GetSummaryValue(node As Node, summary As ISummaryItem) As Object
    ' Retrieve first treeview-level summary by its index.
    Dim firstSummary As TreeviewSummaryItem = node.Treeview.Summaries.Treeview(0)
    ' Retrieve first summary's value.
    Dim firstValue As Decimal = CDec(firstSummary.DataProvider.GetSummaryValue(node, firstSummary))

    ' Calculate this summary value based on the other summary.
    Dim result As Decimal = firstValue / 2
    Return result
End Function

Now that you have the custom data provider implemented, it's time to use it. Below, we add two summaries: one calculates the average value of the specified node control, while the second uses our custom data provider.

We'll add a custom node class ValuedNode with a Value property that holds the value to be aggregated by summaries:

// Node class that holds data.
class ValuedNode : Node
{
    public decimal Value;
}

// Add node control.
NodeNumeric nc = new NodeNumeric
{
    DataFieldName = "Value"
};
nc.AttachTo(tree);

// Add nodes.
ValuedNode node = new ValuedNode { Value = 1 };
node.AttachTo(tree);
node = new ValuedNode { Value = 5 };
node.AttachTo(tree);

// Add summaries.
tree.Summaries.Treeview.LevelsCount = 1;

TreeviewSummaryItem summary = new TreeviewSummaryItem
{
    Operation = eSummaryOperation.Sum,
    NodeControl = nc
};
tree.Summaries.Treeview.Add(summary);    

summary = new TreeviewSummaryItem
{
    Operation = eSummaryOperation.Custom,
    NodeControl = nc,
    // Here's how we use our custom data provider.
    DataProvider = new DependentDataProvider()
};
tree.Summaries.Treeview.Add(summary);
' Node class that holds data.
Class ValuedNode
    Inherits Node
    Public Value As Decimal
End Class

' Add node control.
Dim nc As New NodeNumeric() With {
    .DataFieldName = "Value"
}
nc.AttachTo(tree)

' Add nodes.
Dim node As New ValuedNode() With {
    .Value = 1
}
node.AttachTo(tree)
node = New ValuedNode() With {
    .Value = 5
}
node.AttachTo(tree)

' Add summaries.
tree.Summaries.Treeview.LevelsCount = 1

Dim summary As New TreeviewSummaryItem() With {
    .Operation = eSummaryOperation.Sum,
    .NodeControl = nc
}
tree.Summaries.Treeview.Add(summary)

summary = New TreeviewSummaryItem() With {
    .Operation = eSummaryOperation.Custom,
    .NodeControl = nc,
    ' Here's how we use our custom data provider.
    .DataProvider = New DependentDataProvider()
}
tree.Summaries.Treeview.Add(summary)

That's all. When you run it, you should see a treeview with two nodes and two summaries at the bottom.