Example E1125
Visible to All Users

XAF - How to Use Tree List Editors to Display List Views For ASP.NET Core Blazor And Windows Forms

ASP.NET Core Blazor:

This example describes how to use a tree list control to show hierarchical data in an XAF ASP.NET Core Blazor applications. The example uses the DxTreeListEditor.
If you implement the ITreeNode interface in a business object class, the DxTreeListEditor automatically displays the hierarchical data.

image

Windows Forms

This example describes how to use a tree list control to show hierarchical data in an XAF Windows Forms applications. For this purpose, the example uses the TreeListEditor and CategorizedListEditor supplied with the TreeListEditorsWindowsFormsModule.

image

Implementation Details

The example uses the following techniques:

  1. A List View that defines objects of a type that implements the ITreeNode interface. XAF uses the TreeListEditor to display this View.
    Files to review:

NOTE

Windows Forms only — In ASP.NET Core Blazor, XAF uses DxTreeListEditor when ITreeNode is implemented. You do not need to add a separate module to your project.

  1. A List View that defines objects of a type that implements the ICategorizedItem interface. XAF uses the CategorizedListEditor to display this View.

NOTE

This is valid only for XAF Windows Forms applications. XAF ASP.NET Core Blazor does not support the CategorizedListEditor.

Files to review:
- The Issue class
- The CategoryWithIssues class that is related to the previous class by a One-to-Many relationship.
For details, refer to the following topic: Categorized List.
3. A List View that defines objects of the HCategory type supplied with the Business Class Library. XAF uses the TreeListEditor to display this View. To add the HCategory class to the application's business model, use the following technique: Ways to Add a Business class.
For more information, refer to the following topic: Display a Tree List using the HCategory class.

Files to Review

Documentation

Does this example address your development requirements/objectives?

(you will be redirected to DevExpress.com to submit your response)

Example Code

EFCore/UseTreeListEF/UseTreeListEF.Module/BusinessObjects/Category.cs
C#
using System; using DevExpress.ExpressApp; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Persistent.Base.General; using System.ComponentModel; using DevExpress.Persistent.BaseImpl.EF; namespace HowToUseTreeListEditor.Module { [NavigationItem] public abstract class Category : BaseObject, ITreeNode { protected abstract ITreeNode Parent { get; } protected abstract IBindingList Children { get; } public virtual string Name { get; set; } #region ITreeNode IBindingList ITreeNode.Children { get { return Children; } } string ITreeNode.Name { get { return Name; } } ITreeNode ITreeNode.Parent { get { return Parent; } } #endregion } }
EFCore/UseTreeListEF/UseTreeListEF.Module/BusinessObjects/ProjectGroup.cs
C#
using System; using DevExpress.ExpressApp; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Persistent.Base.General; using System.ComponentModel; using System.Collections.ObjectModel; namespace HowToUseTreeListEditor.Module { public class ProjectGroup : Category { protected override ITreeNode Parent { get { return null; } } BindingList<Project> children; protected override IBindingList Children { get { if (children == null) { children = new BindingList<Project>(Projects); } return children; } } public virtual IList<Project> Projects { get; set; }= new ObservableCollection<Project>(); } }
EFCore/UseTreeListEF/UseTreeListEF.Module/BusinessObjects/Project.cs
C#
using System; using DevExpress.ExpressApp; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Persistent.Base.General; using System.ComponentModel; using System.Collections.ObjectModel; namespace HowToUseTreeListEditor.Module { public class Project : Category { protected override ITreeNode Parent { get { return ProjectGroup; } } BindingList<ProjectArea> children; protected override IBindingList Children { get { if (children == null) { children = new BindingList<ProjectArea>(ProjectAreas); } return children; } } public virtual ProjectGroup ProjectGroup { get; set; } public virtual IList<ProjectArea> ProjectAreas { get; set; } = new ObservableCollection<ProjectArea>(); } }
EFCore/UseTreeListEF/UseTreeListEF.Module/BusinessObjects/ProjectArea.cs
C#
using System; using DevExpress.ExpressApp; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Persistent.Base.General; using System.ComponentModel; namespace HowToUseTreeListEditor.Module { public class ProjectArea : Category { protected override ITreeNode Parent { get { return Project; } } protected override IBindingList Children { get { return new BindingList<object>(); } } public virtual Project Project { get; set; } } }
EFCore/UseTreeListEF/UseTreeListEF.Module/BusinessObjects/Issue.cs
C#
using System; using DevExpress.ExpressApp; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Persistent.Base.General; using DevExpress.Persistent.BaseImpl.EF; namespace HowToUseTreeListEditor.Module { [DefaultClassOptions] public class Issue : BaseObject, ICategorizedItem { public virtual CategoryWithIssues Category { get; set; } public virtual string Subject { get; set; } public virtual string Description { get; set; } ITreeNode ICategorizedItem.Category { get { return Category; } set { Category = (CategoryWithIssues)value; } } } }
EFCore/UseTreeListEF/UseTreeListEF.Module/BusinessObjects/CategoryWithIssues.cs
C#
using System; using DevExpress.ExpressApp; using DevExpress.Persistent.Base; using DevExpress.Persistent.BaseImpl; using DevExpress.Persistent.Validation; using DevExpress.Persistent.Base.General; using System.ComponentModel; using DevExpress.Persistent.BaseImpl.EF; using System.Collections.ObjectModel; using Castle.Components.DictionaryAdapter; using System.ComponentModel.DataAnnotations.Schema; namespace HowToUseTreeListEditor.Module { [NavigationItem] public abstract class CategoryWithIssues : BaseObject, ITreeNode { public virtual IList<Issue> Issues { get; set; } = new ObservableCollection<Issue>(); private List<Issue> allIssues; [NotMapped] public IList<Issue> AllIssues { get { if (allIssues == null) { allIssues = new List<Issue>(); CollectIssuesRecursive(this, allIssues); } return allIssues; } } private void CollectIssuesRecursive(CategoryWithIssues issueCategory, List<Issue> target) { target.AddRange(issueCategory.Issues); foreach (CategoryWithIssues childCategory in issueCategory.Children) { CollectIssuesRecursive(childCategory, target); } } protected abstract ITreeNode Parent { get; } protected abstract IBindingList Children { get; } public virtual string Name { get; set; } #region ITreeNode IBindingList ITreeNode.Children { get { return Children; } } string ITreeNode.Name { get { return Name; } } ITreeNode ITreeNode.Parent { get { return Parent; } } #endregion } }

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.