TreeList Editors Module Overview
- 10 minutes to read
The TreeList Editors module is designed to display information represented by List Views in a tree-like structure. For this purpose, the ASPxTreeList and Tree List controls (from the ASPxTreeList and XtraTreeList libraries) are used in ASP.NET Web Forms and WinForms applications. These controls provide such data representation capabilities as sorting data values against multiple columns, calculating and displaying summary values, node preview, node images, runtime column customization, formatting column and summary values, using advanced editors to display and edit cell values, etc.
To use the ASPxTreeList and TreeList controls, the TreeList Editors module supplies the ASPxTreeListEditor and TreeListEditor for displaying List Views. These List Editors are targeted for objects that implement the ITreeNode interface from the Business Class Library. In addition, the TreeList Editors module supports a categorized tree view, in which tree nodes represent categories with related items. For this purpose, the CategorizedListEditor is supplied. This editor is targeted for category items represented by objects that implement the ICategorizedItem interface.
This topic details the fundamentals for using the TreeList Editors module.
The TreeList Editors module comprises three module projects: TreeListEditorsModuleBase, TreeListEditorsAspNetModule and TreeListEditorsWindowsFormsModule. You can add TreeListEditorsAspNetModule to an ASP.NET Web Forms application and TreeListEditorsWindowsFormsModule to a WinForms application. To do this, invoke the Application Designer and drag the TreeList Editors module from the Toolbox to the Modules panel. Be sure to rebuild the solution after making changes in the Designer.
Until the TreeList Editors Module supports ASP.NET Core Blazor UI, it is possible to implement this functionality manually. The following example demonstrates how to integrate the DevExtreme TreeList widget into your ASP.NET Core Blazor application: XAF Blazor - How to Implement a TreeList Editor.
Note
You can add modules to your application when you use the Solution Wizard to create a new XAF solution. Select modules in the Choose Additional Modules step.
- To add an extra module in code, add it to the XafApplication.Modules or ModuleBase.RequiredModuleTypes list (adding a reference to the module assembly is insufficient).
In .NET applications, you can call the AddTreeListEditors(IModuleBuilder<IWinApplicationBuilder>, Action<TreeListEditorOptions>) method in your WinForms application builder.
Organizing a Tree
To display data in a tree-like structure in the UI, implement the ITreeNode interface in the appropriate business classes.
public interface ITreeNode {
string Name { get; }
ITreeNode Parent { get; }
IBindingList Children { get; }
}
The ITreeNode.Name property specifies a tree node caption. The ITreeNode.Parent property refers to the parent object (tree node). If this property is set to null (Nothing in VB), the object represents the root object (root tree node). The ITreeNode.Children property represents a collection of child objects (child tree nodes).
To see an example of the ITreeNode interface implementation, refer to the Display a Tree List using the ITreeNode Interface topic.
The Business Class Library supplies the HCategory class that implements the ITreeNode interface. You can use it as is, or inherit from it, instead of implementing the ITreeNode interface from scratch. For details, refer to the Display a Tree List using the HCategory Class topic. To see the HCategory class implementation, refer to the %PROGRAMFILES%\DevExpress 24.2\Components\Sources\DevExpress.Persistent\DevExpress.Persistent.BaseImpl.Xpo (or %PROGRAMFILES%\DevExpress 24.2\Components\Sources\DevExpress.Persistent\DevExpress.Persistent.BaseImpl.EFCore) folder, where you will find the HCategory.cs file.
Note
The TreeListEditor and CategorizedListEditor cannot properly display a tree if the hierarchy contains objects of a type that is not assignable from the List View object type (see Type.IsAssignableFrom).
When the TreeListEditors module is added to the application, all List Views that represent ITreeNode objects are displayed via the ASPxTreeListEditor and TreeListEditor by default. This editor builds root nodes from a List View’s objects whose ITreeNode.Parent property is set to null (Nothing in VB). When expanding a node, this editor looks for the List View’s objects that are contained in the node’s ITreeNode.Children collection. The found objects are displayed as child nodes. The following images show an ASPxTreeListEditor and a TreeListEditor.
ASPxTreeListEditor
TreeListEditor
Supporting Node Images
To support node images, implement the ITreeNodeImageProvider interface in a class implementing the ITreeNode interface. As a result, each node will be accompanied by an image.
The ITreeNodeImageProvider declares a single member - the ITreeNodeImageProvider.GetImage method. In this method, return the image corresponding to a tree node.
To see an example of the ITreeNodeImageProvider interface implementation, refer to the Node Images in a Tree List topic.
Implementing the Category-Items Scenario
In most scenarios, a tree node represents a category that can have related items. The following business model can be implemented in terms of the Category-Items scenario. The root category is represented by objects of the ProjectGroup class (“.Net”, “VCL”, …). This category’s child category is represented by Project type objects (“XtraGrid”, “XtraEditors”, “QuantumGrid”, …). There may be more levels in this hierarchy. For example, each Project can contain a list of its own Areas: “Columns”, “RepositoryItems”, “MaskEdit”, etc. These objects should implement the ITreeNode interface to be displayed as a tree. At the same time, there can be Issue objects related to specific categories (to a ProjectGroup, Project or ProjectArea). In other words, each category is related to Issue objects by the One-to-Many relationship. When displaying the Issue List View, you may need to see a tree of categories and a list of Issue objects related to the currently selected category, as shown in the image below.
This image demonstrates how the Windows Forms CategorizedListEditor displays the Issue List View. The TreeList Editors module supplies this List Editor for the scenarios, as defined above. It displays the List Views that represent objects of the ICategorizedItem type, so the Issue class from the example above should implement the ICategorizedItem interface.
To learn how to implement the example defined above, refer to the Categorized List topic.
It is not necessary to display Issue List Views via the CategorizedListEditor. For instance, you can use an ordinary GridListEditor for nested Issue List Views. For this purpose, do the following.
- Invoke the Model Editor for the Windows Forms application project.
Right-click the Views node and select Add… | ListView in the invoked context menu.
- For the newly created node, specify the Id property and set the ModelClass property to the type that implements the ICategorizedItem interface (e.g., “Issue” in this example).
- Right-click the new node and choose Generate content.
- Navigate to the Detail View node that defines the Detail View with a collection of ICategorizedItem objects (e.g., “ProjectArea”, in this example). Locate the child View Item node that corresponds to this collection. Set its View property to the node that you created in the previous steps.
Accessing a TreeListEditor or CategorizedListEditor
You can customize the TreeListEditor and CategorizedListEditor List Editors, or the TreeList control exposed via the List Editor’s ListEditor.Control property. To access a List Editor in code, create a View Controller and handle its ViewController.ViewControlsCreated event, or override the OnViewControlsCreated protected method. The following code snippets illustrate this.
Access a TreeListEditor:
using DevExpress.ExpressApp.TreeListEditors.Win;
using DevExpress.XtraTreeList;
using DevExpress.Persistent.Base.General;
//...
public partial class TreeListController : ViewController {
public TreeListController() {
TargetViewType = ViewType.ListView;
TargetObjectType = typeof(ITreeNode);
}
protected override void OnViewControlsCreated() {
base.OnViewControlsCreated();
ListView view = (ListView)View;
TreeListEditor listEditor = (TreeListEditor)view.Editor;
TreeList treeList = listEditor.TreeList;
// Access TreeList object here.
}
}
Access a CategorizedListEditor:
using DevExpress.ExpressApp.TreeListEditors.Win;
using DevExpress.XtraTreeList;
using DevExpress.Persistent.Base.General;
//...
public partial class CategorizedListController : ViewController {
public CategorizedListController() {
TargetViewType = ViewType.ListView;
TargetObjectType = typeof(ICategorizedItem);
}
protected override void OnViewControlsCreated() {
ListView view = (ListView)View;
CategorizedListEditor listEditor = (CategorizedListEditor)view.Editor;
ListView categoriesListView = listEditor.CategoriesListView;
TreeListEditor treeListEditor = (TreeListEditor)categoriesListView.Editor;
TreeList treeList = treeListEditor.TreeList;
// Do what you want with the tree list
}
}
Since Controllers are implemented in modules, add a reference to the TreeList Editors module to the required module. You will need to set a reference to the DevExpress.XtraTreeList.v24.2.dll assembly as well.
Filtering a Tree List
To filter a tree list, XAF applies the ListView.CollectionSource filter criteria (CollectionSourceBase.Criteria) to the tree list’s root objects only. Child collections are not processed because they are stored in the ITreeNode.Children properties and are not related to the root collection source.
List View tree list controls - TreeList and ASPxTreeList - provide advanced filtering features. For example, the controls support filtering operators and can filter root and child objects. Follow the links below for more information:
The following resource demonstrates how to use these features in XAF applications:
- The List Editors | Tree | Filtering section in the Feature Center demo (%PUBLIC%\Documents\DevExpress Demos 24.2\Components\XAF\FeatureCenter.NETFramework.XPO) or the Feature Center demo online
Boolean Properties in the ASPxTreeList
XAF ASPxTreeList integration code is not designed to immediately show the new value of a Boolean property if it was changed on the server side. For instance, a new value is not shown immediately if it is changed by an Action (a page refresh is required). To avoid this restriction, use the following code.
using DevExpress.Web.ASPxTreeList;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.TreeListEditors.Web;
// ...
public class RemoveTreeListDataCellTemplateController : ViewController {
public RemoveTreeListDataCellTemplateController() : base() { }
protected override void OnActivated() {
base.OnActivated();
ListView listView = View as ListView;
if (listView != null && listView.Editor != null) {
listView.Editor.ControlsCreated += Editor_ControlsCreated;
}
}
void Editor_ControlsCreated(object sender, EventArgs e) {
ASPxTreeListEditor treeListEditor = sender as ASPxTreeListEditor;
if (treeListEditor != null) {
TreeListDataColumn column =
treeListEditor.TreeList.Columns["BoolProperty"] as TreeListDataColumn;
if (column != null) {
column.DataCellTemplate = null;
}
}
}
}
With this code, the ASPxTreeList control will show Boolean values using the TreeListDataColumn. For details, see TreeListDataColumn.DataCellTemplate.