Display a Tree List using the ITreeNode Interface

To display data in a tree-like structure, the ITreeNode interface should be implemented in the appropriate business classes. The objects that support this interface are displayed via the ASPxTreeList and TreeList controls from the ASPxTreeList and XtraTreeList libraries. This is provided by the TreeList Editors module. To learn more about the ITreeNode interface and the List Editor supplied for it with the TreeList Editors module, refer to the TreeList Editors Module Overview topic. This topic demonstrates how to implement the ITreeNode interface.

Tip

A complete sample project is available in the DevExpress Code Examples database at http://www.devexpress.com/example=E1125.

We will implement a tree structure like this:

CategoryTreeList

CategoryTreeList Legend

For this purpose, we will implement the ProjectGroup, Project and ProjectArea classes. All of them will be inherited from an abstract class that will implement the ITreeNode interface. To display a tree of these objects, an item that corresponds to that abstract class will be added to the navigation control. When clicking this item, all the objects of the types derived from the abstract class will be organized in a tree via the TreeListEditor. This editor will be provided by the TreeList Editors module, which we will add to the application.

Important

The example below is for XPO. If you use Entity Framework, you can find a similar Category entity source at C:\Program Files (x86)\DevExpress 18.2\Components\Sources\DevExpress.Persistent\DevExpress.Persistent.BaseImpl.EF\HCategory.cs.

  • Implement an abstract Category class as shown in the following code:

    using System.ComponentModel;
    using DevExpress.Persistent.Base;
    using DevExpress.Persistent.Base.General;
    using DevExpress.Persistent.BaseImpl;
    using DevExpress.Xpo;
    //...
    [NavigationItem]
    public abstract class Category : BaseObject, ITreeNode {
       private string name;
       protected abstract ITreeNode Parent {
          get;
       }
       protected abstract IBindingList Children {
          get;
       }
       public Category(Session session) : base(session) {}
       public string Name {
          get {
             return name;
          }
          set{
             SetPropertyValue("Name", ref name, value);
          }
       }
       #region ITreeNode
       IBindingList ITreeNode.Children{
          get{
             return Children;
          }
       }
       string ITreeNode.Name{
          get {
             return Name;
          }
       }
       ITreeNode ITreeNode.Parent{
          get{
             return Parent;
          }
       }
       #endregion
    }
    

    The NavigationItemAttribute is applied so that the corresponding navigation item is added to the navigation control.

    The Parent and Children properties will be overridden in the descendant classes, to return objects of the required types.

  • Implement the ProjectGroup, Project and ProjectArea classes by inheriting them from the Category class. The following code demonstrates how to do this:

    using System.ComponentModel;
    using DevExpress.Persistent.Base.General;
    using DevExpress.Xpo;
    //...
    public class ProjectGroup : Category{
       protected override ITreeNode Parent {
          get {
             return null;
          }
       }
       protected override IBindingList Children {
          get {
             return Projects;
          }
       }
       public ProjectGroup(Session session) : base(session){}
       public ProjectGroup(Session session, string name) : base(session) {
          this.Name = name;
       }
       [Association("ProjectGroup-Projects"), Aggregated]
       public XPCollection<Project> Projects {
          get {
             return GetCollection<Project>("Projects");
          }
       }
    }
    
    public class Project : Category {
       private ProjectGroup projectGroup;
       protected override ITreeNode Parent {
          get {
             return projectGroup;
          }
       }
       protected override IBindingList Children {
          get {
             return ProjectAreas;
          }
       }
       public Project(Session session) : base(session) {}
       public Project(Session session, string name) : base(session) {
          this.Name = name;
       }
       [Association("ProjectGroup-Projects")]
       public ProjectGroup ProjectGroup {
          get {
             return projectGroup;
          }
          set {
             SetPropertyValue("ProjectGroup", ref projectGroup, value);
          }
       }
       [Association("Project-ProjectAreas"), Aggregated]
       public XPCollection<ProjectArea> ProjectAreas {
          get {
             return GetCollection<ProjectArea>("ProjectAreas");
          }
       }
    }
    
    public class ProjectArea : Category {
       private Project project;
       protected override ITreeNode Parent {
          get {
             return project;
          }
       }
       protected override IBindingList Children {
          get {
             return new BindingList<object>();
          }
       }
       public ProjectArea(Session session) : base(session) {}
       public ProjectArea(Session session, string name) : base(session) {
          this.Name = name;
       }
       [Association("Project-ProjectAreas")]
       public Project Project {
          get {
             return project;
          }
          set {
             SetPropertyValue("Project", ref project, value);
          }
       }
    }
    
    Note

    There are two important requirements the business classes must satisfy:

    • The parent and child classes that correspond to tree list nodes should inherit the same base class that implements the ITreeNode interface. In the code above, the ProjectGroup, Project and ProjectArea classes are inherited from the Category class.
    • It is not possible to have more than one root class in a tree list. In the code above, the ProjectGroup is the root class.
  • Add the TreeList Editors module to the Windows Forms application project. For this purpose, invoke the Application Designer and drag the module from the Toolbox to the Modules panel.
  • Run the Windows Forms application. Click the Category item in the navigation control. Then, create ProjectGroup, Project and ProjectArea objects via the New Action. You will see that these objects will be displayed as a tree by the Category List View:

    TreeListEditor

Tree nodes can have associated images. These images are displayed by the Tree List Editors within the nodes. For details, refer to the Node Images in a Tree List interface.

You can also display a collection of items for each category node to the right of the tree list. For details, refer to the Categorized List topic.

If you do not need to organize the strong structure as demonstrated above, but wish to use the ready-to use HCategory class implementing the ITreeNode interface, refer to the Display a Tree List using the HCategory Class topic.