In This Topic
Overview
One of the unique and popular features of the FlexGrid control is the ability to add hierarchical grouping to regular data grid and display it in a tree like structure called Tree Grid. The Tree Grid control is very similar to the one you see in a TreeView control. It shows an indented structure with collapse or expand icon next to each node row so the user can expand and collapse the outline to see the desired level of detail by clicking on the nodes.
Although, you can create simple outline trees using FlexGrid grouping, Tree Grid helps you implement more advanced use cases such as displaying customer and order details. In a usual grid showing such data, it is difficult to see the details of each customer and order. In such case, you can create a Tree Grid to group the data in a hierarchical structure for better view and accessibility of information.
Quick Binding
Loading data in a Tree Grid is exactly the same as loading in a regular grid. If the data source is available at design time, you can use the Visual Studio Property Window to set the grid's property of the class and bind the grid to the data without writing even a single line of code. For detailed steps, see Bound Mode.
You can also set the DataSource property through code. Following code shows how to use the DataSource property to populate data in the WinForms Tree Grid.
The code uses an OleDbDataAdapter to fill a DataTable with data, then assigns datatable to DataSource property of the grid. To turn this regular grid in a Tree grid, you need to insert the node rows which is discussed in the section below.
Create Nodes (Bound and Unbound Mode)
To create a Tree Grid, FlexGrid introduces a concept of Node rows. These rows do not contain regular data and are simply header rows under which similar data is grouped, just like nodes in a usual TreeView control. You can also define the hierarchy of these nodes by setting the property. These nodes can be collapsed and expanded to hide or show the data they contain. The Tree Grid can be displayed in any column, defined by the property. By default, this property is set to -1, which causes the tree not to be displayed at all.
Bound Mode (Using InsertNode Method)
You can create node rows using InsertNode method of the class which inserts a new node row at a specified index. This is the 'low-level' way of inserting totals and building outlines.
The GroupBy method used here inserts node rows by grouping identical values. To obtain a Node object, you can either use return value of the InsertNode method or retrieve the node for an existing row using the property.
Use the following code to create nodes using InsertNode method in the bound WinForms Tree Grid.
The code also calls the AutoSizeCols method to ensure that the column is wide enough to accommodate the Tree Grid. Finally, it calls the GridTree.Show method to display the nodes.
Also, the class provides following methods and properties, based on TreeView object model, which can be used to manage the Tree Grid.
- Checked: Gets or sets the check state of cell defined by Node.Row and GridTree.Column.
- Collapsed/Expanded: Gets or sets collapsed or expanded state of the node.
- Data: Gets or sets value in the cell defined by Node.Row and GridTree.Column.
- Image: Gets or sets image in the cell defined by Node.Row and GridTree.Column.
- Level: Gets or sets node level in the Tree Grid.
You can also explore the outline structure using the following properties and methods:
- Children: Gets number of child nodes under this node.
- GetCellRange: Gets the CellRange object that described range of rows that belong to this node.
- GetNode: Gets the node that has a given relationship to this node (parent, first child, next sibling, and so on).
- Nodes: Gets a node array containing child nodes of this node.
Bound Mode (Using Subtotal Method)
In bound mode, another way to create nodes is using the method. To make the Tree Grid really useful, the node rows must include summary information for the data they contain.
If you create Tree Grid using the Subtotal method, the subtotals are added automatically. The method scans the entire grid and automatically inserts node rows with optional subtotals at locations where the grid data changes.
This is the 'high-level' way of inserting totals and building outlines.
The first parameter of the Subtotal method is AggregateEnum enumeration which calculates various types of aggregates like Sum, Average, Count, Max, Min, and others. In the code below, Subtotal method of the C1FlexGrid class is used for creating nodes in a bound WinForms Tree Grid.
private void SubtotalNode_Bound_Load(object sender, EventArgs e)
{
// Binding FlexGrid
BindGrid(_gridBound);
// shows Tree in Bound FlexGrid
CreateTree(_gridBound);
// Creates Subtotal(s) in Bound FlexGrid
CreateSubTotal(_gridBound);
}
public void BindGrid(C1FlexGrid grid)
{
DataTable dt = new DataTable();
dt.Columns.Add("ID", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("Course", typeof(string));
dt.Columns.Add("Score", typeof(int));
dt.Columns.Add("Attendance", typeof(int));
dt.Columns.Add("Country", typeof(string));
//Sample Data
dt.Rows.Add(1, "Helen Bennett", "ComputerScience", 79, 84, "Spain");
dt.Rows.Add(2, "Ana Trujillo", "Biology", 78, 87, "Mexico");
dt.Rows.Add(3, "Antonio Moreno", "Aeronautics", 71, 70, "Spain");
dt.Rows.Add(4, "Paolo Accorti", "Biology", 74, 63, "Spain");
dt.Rows.Add(5, "Elizabeth Brown", "ComputerScience", 80, 93, "Mexico");
dt.Rows.Add(6, "Jaime Yorres", "Biology", 61, 48, "Spain");
dt.Rows.Add(7, "Yvonne Moncada", "Aeronautics", 85, 78, "Mexico");
dt.Rows.Add(8, "Martine Rancé", "Aeronautics", 67, 81, "Spain");
dt.Rows.Add(9, "Sergio Gutiérrezy", "ComputerScience", 62, 58, "Mexico");
dt.Rows.Add(10, "Thomas Hardy", "Aeronautics", 94, 92, "Mexico");
dt.Rows.Add(11, "Patricio Simpson", "Aeronautics", 46, 52, "Spain");
dt.Rows.Add(12, "Maria Anders", "ComputerScience", 85, 73, "Spain");
grid.DataSource = dt;
grid.AutoSizeCols();
(grid.DataSource as DataTable).DefaultView.Sort = "Course";
}
// Creates Tree in FlexGrid
public void CreateTree(C1FlexGrid grid)
{
grid.Tree.Column = 1;
grid.Tree.Style = TreeStyleFlags.SimpleLeaf;
grid.Tree.Show(1);
grid.AutoSizeCols();
}
public void CreateSubTotal(C1FlexGrid grid)
{
// Clears any existing subtotal(s) present in grid
grid.Subtotal(AggregateEnum.Clear);
// Adds subtotal in grid with Level: 1, Group: 'Course' column, Aggregate(Average): Score, Attendance
grid.Subtotal(AggregateEnum.Average, 1, 3, 3, 4, "Average for {0}");
grid.AutoSizeCols();
}
Private Sub SubtotalNode_Bound_Load(ByVal sender As Object, ByVal e As EventArgs)
' Binding FlexGrid
BindGrid(_gridBound)
' Shows Tree in Bound FlexGrid
CreateTree(_gridBound)
' Creates Subtotal(s) in Bound FlexGrid
CreateSubTotal(_gridBound)
End Sub
Public Sub BindGrid(ByVal grid As C1FlexGrid)
Dim dt As DataTable = New DataTable()
dt.Columns.Add("ID", GetType(Integer))
dt.Columns.Add("Name", GetType(String))
dt.Columns.Add("Course", GetType(String))
dt.Columns.Add("Score", GetType(Integer))
dt.Columns.Add("Attendance", GetType(Integer))
dt.Columns.Add("Country", GetType(String))
'Sample Data
dt.Rows.Add(1, "Helen Bennett", "ComputerScience", 79, 84, "Spain")
dt.Rows.Add(2, "Ana Trujillo", "Biology", 78, 87, "Mexico")
dt.Rows.Add(3, "Antonio Moreno", "Aeronautics", 71, 70, "Spain")
dt.Rows.Add(4, "Paolo Accorti", "Biology", 74, 63, "Spain")
dt.Rows.Add(5, "Elizabeth Brown", "ComputerScience", 80, 93, "Mexico")
dt.Rows.Add(6, "Jaime Yorres", "Biology", 61, 48, "Spain")
dt.Rows.Add(7, "Yvonne Moncada", "Aeronautics", 85, 78, "Mexico")
dt.Rows.Add(8, "Martine Rancé", "Aeronautics", 67, 81, "Spain")
dt.Rows.Add(9, "Sergio Gutiérrezy", "ComputerScience", 62, 58, "Mexico")
dt.Rows.Add(10, "Thomas Hardy", "Aeronautics", 94, 92, "Mexico")
dt.Rows.Add(11, "Patricio Simpson", "Aeronautics", 46, 52, "Spain")
dt.Rows.Add(12, "Maria Anders", "ComputerScience", 85, 73, "Spain")
grid.DataSource = dt
grid.AutoSizeCols()
TryCast(grid.DataSource, DataTable).DefaultView.Sort = "Course"
End Sub
' Creates Tree in FlexGrid
Public Sub CreateTree(ByVal grid As C1FlexGrid)
grid.Tree.Column = 1
grid.Tree.Style = TreeStyleFlags.SimpleLeaf
grid.Tree.Show(1)
grid.AutoSizeCols()
End Sub
Public Sub CreateSubTotal(ByVal grid As C1FlexGrid)
' Clears any existing subtotal(s) present in grid
grid.Subtotal(AggregateEnum.Clear)
' Adds subtotal in grid with Level: 1, Group: 'Course' column, Aggregate(Average): Score, Attendance
grid.Subtotal(AggregateEnum.Average, 1, 3, 3, 4, "Average for {0}")
grid.AutoSizeCols()
End Sub
Unbound Mode (Using Subtotal Method)
The Subtotal method is a very convenient and flexible way to create a tree grid. It has a number of overloads that allow you to specify which columns are to be grouped on and totaled on by index or by name, whether to include a caption in the node rows that it inserts, how to perform the grouping, and so on.
In the code below, Subtotal method of the C1FlexGrid class is used for creating nodes in an unbound WinForms Tree Grid.
Unbound Mode(Using IsNode Property)
In an unbound grid, you can turn regular rows into node rows by simply setting the IsNode property to true. If you try to turn a regular data bound row into a node, it causes the grid to throw an exception.
Use the following code to create nodes using IsNode property in an unbound WinForms Tree Grid.
See Also