商信互联
为了以树状结构显示数据,应该在适当的业务类中实现ITreeNode接口。支持此接口的对象通过ASPxTreeList和XtraTreeList库中的ASPxTreeList和TreeList控件显示。这是由TreeList编辑器模块提供的。要了解有关ITreeNode接口和TreeList编辑器模块为其提供的列表编辑器的更多信息,请参考TreeList编辑器模块概述主题。本主题演示如何实现ITreeNode接口。
可在http://www.devexpress.com/example=E1125的DevExpress代码示例数据库中找到完整的示例项目。
我们将实现这样的树结构:
为此,我们将实现ProjectGroup,Project和ProjectArea类。它们都将从实现ITreeNode接口的抽象类继承。为了显示这些对象的树,将与该抽象类相对应的项添加到导航控件中。单击此项目时,将从抽象类派生的所有类型的对象都将通过TreeListEditor以树的形式进行组织。该编辑器将由TreeList编辑器模块提供,我们将其添加到应用程序中。
以下示例适用于XPO。如果使用实体框架,则可以在C:\ Program Files(x86)\ DevExpress 19.2 \ Components \ Sources \ DevExpress.Persistent \ DevExpress.Persistent.BaseImpl.EF \ HCategory.cs中找到类似的类别实体源。
实现一个抽象的Category类,如以下代码所示:
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(nameof(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
}
Imports System.ComponentModel
Imports DevExpress.Persistent.Base
Imports DevExpress.Persistent.Base.General
Imports DevExpress.Persistent.BaseImpl
Imports DevExpress.Xpo
'...
<NavigationItem> _
Public MustInherit Class Category
Inherits BaseObject
Implements ITreeNode
Private fName As String
Protected MustOverride ReadOnly Property Parent() As ITreeNode
Protected MustOverride ReadOnly Property Children() As IBindingList
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Property Name() As String
Get
Return fName
End Get
Set
SetPropertyValue(NameOf(Name), fName, Value)
End Set
End Property
#Region "ITreeNode"
Private ReadOnly Property ICategorizedItem_Children() As IBindingList _
Implements ITreeNode.Children
Get
Return Children
End Get
End Property
Private ReadOnly Property ICategorizedItem_Name() As String Implements ITreeNode.Name
Get
Return Name
End Get
End Property
Private ReadOnly Property ICategorizedItem_Parent() As ITreeNode Implements ITreeNode.Parent
Get
Return Parent
End Get
End Property
#End Region
End Class
所述NavigationItemAttribute被施加,使得相应的导航项目被添加到导航控制。
Parent和Children属性将在后代类中被覆盖,以返回所需类型的对象。
通过从Category类继承它们来实现ProjectGroup,Project和ProjectArea类。以下代码演示了如何执行此操作:
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>(nameof(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(nameof(ProjectGroup), ref projectGroup, value);
}
}
[Association("Project-ProjectAreas"), Aggregated]
public XPCollection<ProjectArea> ProjectAreas {
get {
return GetCollection<ProjectArea>(nameof(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(nameof(Project), ref project, value);
}
}
}
Imports System.ComponentModel
Imports DevExpress.Persistent.Base.General
Imports DevExpress.Xpo
'...
Public Class ProjectGroup
Inherits Category
Protected Overrides ReadOnly Property Parent() As ITreeNode
Get
Return Nothing
End Get
End Property
Protected Overrides ReadOnly Property Children() As IBindingList
Get
Return Projects
End Get
End Property
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Sub New(ByVal session As Session, ByVal name As String)
MyBase.New(session)
Me.Name = name
End Sub
<Association("ProjectGroup-Projects"), Aggregated> _
Public ReadOnly Property Projects() As XPCollection(Of Project)
Get
Return GetCollection(Of Project)(NameOf(Projects))
End Get
End Property
End Class
Public Class Project
Inherits Category
Private fProjectGroup As ProjectGroup
Protected Overrides ReadOnly Property Parent() As ITreeNode
Get
Return fProjectGroup
End Get
End Property
Protected Overrides ReadOnly Property Children() As IBindingList
Get
Return ProjectAreas
End Get
End Property
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Sub New(ByVal session As Session, ByVal name As String)
MyBase.New(session)
Me.Name = name
End Sub
<Association("ProjectGroup-Projects")> _
Public Property ProjectGroup() As ProjectGroup
Get
Return fProjectGroup
End Get
Set
SetPropertyValue(NameOf(ProjectGroup), fProjectGroup, Value)
End Set
End Property
<Association("Project-ProjectAreas"), Aggregated> _
Public ReadOnly Property ProjectAreas() As XPCollection(Of ProjectArea)
Get
Return GetCollection(Of ProjectArea)(NameOf(ProjectAreas))
End Get
End Property
End Class
Public Class ProjectArea
Inherits Category
Private fProject As Project
Protected Overrides ReadOnly Property Parent() As ITreeNode
Get
Return fProject
End Get
End Property
Protected Overrides ReadOnly Property Children() As IBindingList
Get
Return New BindingList(Of Object)()
End Get
End Property
Public Sub New(ByVal session As Session)
MyBase.New(session)
End Sub
Public Sub New(ByVal session As Session, ByVal name As String)
MyBase.New(session)
Me.Name = name
End Sub
<Association("Project-ProjectAreas")> _
Public Property Project() As Project
Get
Return fProject
End Get
Set
SetPropertyValue(NameOf(Project), fProject, Value)
End Set
End Property
End Class
业务类别必须满足两个重要要求:
运行Windows窗体应用程序。单击导航控件中的类别项。然后,通过“新建操作”创建ProjectGroup,Project和ProjectArea对象。您将看到类别列表视图将这些对象显示为树:
树节点可以具有关联的图像。这些图像由节点内的“树列表”编辑器显示。有关详细信息,请参阅“树列表”界面中的“节点图像”。
您还可以在树列表的右侧显示每个类别节点的项目集合。有关详细信息,请参阅“分类列表”主题。
如果您不需要组织如上所示的强大结构,但希望使用实现ITreeNode接口的即用型HCategory类,请参阅使用HCategory类显示树列表主题。