Skip to main content
All docs
V17.2

Creating a Tree-Like Structure of Rows

  • 7 minutes to read

Rows of all types can hold a collection of child rows. So data in the vertical grids (VGridControl and PropertyGridControl) can be organized into a tree-like structure where parent rows can be expanded or collapsed to show and hide their children. This topic explains how to organize rows into such a hierarchical manner.

Tree Structure Overview

Organizing rows into a tree is useful for several reasons. First, it is necessary when using category rows since they are specifically designed to hold a collection of child rows. Creating a hierarchy of rows can also significantly increase the readability of data. Consider the following cases where a tree of rows is likely to be used:

  • Data displayed by rows is hierarchical by nature. For instance, if rows in your control display personnel information amongst other rows it is natural to display a row showing the person’s name as the parent row and then rows which display the individual’s details (occupation, date of birth, etc) as child rows.
  • Arranging data into a tree enables you to show only a subset of the most used fields when the application launches. End-users will then be able to expand rows to see details that are rarely needed. This will allow you to use the screen space more efficiently displaying fewer rows at a time.
  • Parent and child rows due to their nature have to be kept together. If a parent row is moved to another position within the grid or to the Customization Form, its child rows will be moved with it.

The image below displays an example of arranging vertical grid rows into a tree.

TreeStructure - Sample

At the object level, rows are organized into nesting collections to represent the tree. Rows which reside at the control’s root level are stored within the VGridControlBase.Rows vertical grid property. This property is represented by the VGridRows object which is a collection of BaseRow descendants (rows of any type). Each row in turn can hold a collection of child rows in its BaseRow.ChildRows property. This property’s type is VGridRows and so able to hold rows of any type, these rows can also have their own children and so on.

When objects are arranged into a nesting structure as described above, they cannot be directly accessed on an individual basis. To access object’s in this type of structure you need to write a piece of code which will loop through all the objects until you reach the desired one, However the Rows Iterator technology can simplify such operations. Refer to the Accessing Rows and Navigating Through Rows topics for more information on how to obtain a desired row object and how to move the focus from row to row. The Expanding and Collapsing Rows topic describes the means by which rows can be expanded and collapsed.

Creating a Tree at design time

At design time rows can be arranged into a tree by using the Rows page of the VerticalGrid Designer. When rows are added to the grid using the Add or Retrieve Fields buttons on this page, they will be placed at root level. However, you only need to drag and drop rows to rearrange them into a tree. The following drag and drop operations are available:

  • Drag a row to a different row which will move the row which has been dragged into the child collection of the destination row.
  • Drag a row to a different row whilst holding down the CTRL key which will insert the dragged row before the destination row (on the same level).

Let’s consider an example of arranging rows into a hierarchy. The sample below assumes that you have the row structure illustrated in the image below.

TreeStructure - DesignTime - Start

Follow the steps below:

  • Add a category row and set its RowProperties.Caption property to ‘Main‘. A category row can be added by clicking on the down arrow which corresponds to the Add button and then choosing the CategoryRow item from the dropdown menu.

    TreeStructure - DesignTime - AddCategory

  • Drag the ‘Model‘ row to the added category.

    TreeStructure - DesignTime - MoveFirst

  • Drag the ‘Category‘ row to the ‘Model‘ row.

    TreeStructure - DesignTime - MoveSecond

  • Finally, drag the ‘Trademark‘ row to the ‘Model‘ row whilst holding down the CTRL key.

    TreeStructure - DesignTime - MoveLast

Note: end-users can also change the structure of rows using the same drag and drop operations. Please refer to the Using drag and drop topic of the End-user Capabilities section for details on how this can be performed and a list of restrictions.

Creating a Tree at Runtime

This section will provide two examples. Their results will be the same and equivalent to the design-time sample, although they will differ in starting points. The first assumes that the ‘Trademark‘, ‘Model‘ and ‘Category‘ rows have already been added to the control’s root level collection of rows. In other words, it performs the same steps as in the design time sample and adds a new category row and moves other rows to their desired positions. The VGridControlBase.MoveRow method is used to change a rows location.


using DevExpress.XtraVerticalGrid.Rows;
// ...
// adding a category row
CategoryRow rowMain = new CategoryRow("Main");
vGridControl1.Rows.Add(rowMain);
// moving the Model row
vGridControl1.MoveRow(rowModel, rowMain, false);
// moving the Category row
vGridControl1.MoveRow(rowCategory, rowModel, false);
// moving the Trademark row
vGridControl1.MoveRow(rowTrademark, rowModel, true);

Note: as you can see from the above sample, rows are referred to in code by their names. This is possible because row objects are derived from the Component class. Please refer to the Accessing Rows topic for more information on how to access rows in code.

The following sample assumes that there are no rows present in the control prior to the code being executed, if this is the case, then there is no need to use the VGridControlBase.MoveRow method. Rows are added to their desired positions using collection methods that must contain them.


using DevExpress.XtraVerticalGrid.Rows;
// ...
// adding a category row to the root level
CategoryRow rowMain = new CategoryRow("Main");
vGridControl1.Rows.Add(rowMain);
// creating and modifying the Trademark row
EditorRow rowTrademark = new EditorRow("Trademark");
rowTrademark.Properties.Caption = "Trademark";
// adding the Trademark row to the Main row's child collection
rowMain.ChildRows.Add(rowTrademark);
// creating and modifying the Model row
EditorRow rowModel = new EditorRow("Model");
rowModel.Properties.Caption = "Model";
// adding the Model row to the Main row's child collection
rowMain.ChildRows.Add(rowModel);
// creating and modifying the Category row
EditorRow rowCategory = new EditorRow("Category");
rowCategory.Properties.Caption = "Category";
// adding the Category row to the Model row's child collection
rowModel.ChildRows.Add(rowCategory);

Useful Members for Managing Rows Arranged into a Tree

When rows in a vertical grid are arranged into a tree, you will need a way to determine the parent of a specific row, its level within the hierarchy, etc. The members listed below provide this information :

  • BaseRow.ParentRow - returns the row’s parent.
  • BaseRow.Level - returns the zero-based index for the row’s nesting level.
  • BaseRow.Index - returns the row’s index in the parents child collection.
  • BaseRow.HasAsChild - returns a value indicating whether the row specified is present in its child tree.
  • BaseRow.HasAsParent - returns a value indicating whether the row is present in the child tree of the one specified.