Our What's New in v24.2 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.
When data is displayed as a tree, you may need to show the objects associated with the currently selected node in the same List View. XAF enables you to do this by implementing the ICategorizedItem interface in the associated objects, and using the CategorizedListEditor provided by the TreeList Editors module. This topic demonstrates an implementation of categorized list with the business classes defined in the Display a Tree List using the ITreeNode Interface topic.
In the Display a Tree List using the ITreeNode Interface topic, the ProjectGroup, Project and ProjectArea classes are implemented by inheriting from an abstract Category class, which implements the ITreeNode interface. Now, we will implement the Issue class that will be related to the Category class by the Many-to-One relationship. In addition, to display the Issue List View via the CategorizedListEditor, the Issue class will implement the ICategorizedItem interface. For details on this interface and the CategorizedListEditor, refer to the TreeList Editors Module Overview topic.
Implement the Issue class as shown in the code below:
The public property that is returned by the private Category property, which implicitly implements the ICategorizedItem interface, must be called “Category”. This is currently required by the internal infrastructure.
Modify the Category class to add an association with Issue objects:
[NavigationItem]
publicabstractclassCategory : BaseObject, ITreeNode {
publicvirtualIList<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;
}
}
privatevoidCollectIssuesRecursive(Category issueCategory, List<Issue> target) {
target.AddRange(issueCategory.Issues);
foreach(Category childCategory in issueCategory.Children) {
CollectIssuesRecursive(childCategory, target);
}
}
//...
}
// Make sure that you use options.UseChangeTrackingProxies() in your DbContext settings.
[NavigationItem]
publicabstractclassCategory : BaseObject, ITreeNode {
[Association("Category-Issues")]
public XPCollection<Issue> Issues {
get {
return GetCollection<Issue>(nameof(Issues));
}
}
private XPCollection<Issue> allIssues;
public XPCollection<Issue> AllIssues {
get {
if (allIssues == null) {
allIssues = new XPCollection<Issue>(Session, false);
CollectIssuesRecursive(this, allIssues);
allIssues.BindingBehavior = CollectionBindingBehavior.AllowNone;
}
return allIssues;
}
}
privatevoidCollectIssuesRecursive(Category issueCategory, XPCollection<Issue> target) {
target.AddRange(issueCategory.Issues);
foreach (Category childCategory in issueCategory.Children) {
CollectIssuesRecursive(childCategory, target);
}
}
//...
}
<NavigationItem> _
PublicMustInheritClass Category
Inherits BaseObject
Implements ITreeNode
<Association("Category-Issues")> _
PublicReadOnlyProperty Issues() As XPCollection(Of Issue)
GetReturn GetCollection(Of Issue)(NameOf(Issues))
EndGetEndPropertyPrivate fAllIssues As XPCollection(Of Issue)
PublicReadOnlyProperty AllIssues() As XPCollection(Of Issue)
GetIf fAllIssues IsNothingThen
fAllIssues = New XPCollection(Of Issue)(Session, False)
CollectIssuesRecursive(Me, fAllIssues)
fAllIssues.BindingBehavior = CollectionBindingBehavior.AllowNone
EndIfReturn fAllIssues
EndGetEndPropertyPrivateSub CollectIssuesRecursive(ByVal issueCategory As Category, _
ByVal target As XPCollection(Of Issue))
target.AddRange(issueCategory.Issues)
ForEach childCategory As Category In issueCategory.Children
CollectIssuesRecursive(childCategory, target)
Next childCategory
EndSub'...EndClass
Check that the TreeList Editors module is added to the Windows Forms application project, and run the application. Invoke the Issue List View. Select a tree node in the tree list to the left and execute the New Action, to create an Issue for the corresponding Category object. To the right of the tree list, a list of Issue objects associated with the currently selected tree node is displayed.
Was this page helpful?
Thanks for your feedback!
How can we improve this help topic?
Additional comments/thoughts:
If you have any questions, submit a ticket to our Support Center.