Categorized List

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 how to perform this task using the business classes defined in the Display a Tree List using the ITreeNode Interface topic.

Tip

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

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:

using DevExpress.Persistent.Base.General;
//...
[DefaultClassOptions]
public class Issue : BaseObject, ICategorizedItem {
   private Category category;
   private string subject;
   private string description;
   public Issue(Session session) : base(session) {}
   public Issue(Session session, string subject) : base(session) {
      this.subject = subject;
   }
   [Association("Category-Issues")]
   public Category Category {
      get {
         return category;
      }
      set {
         SetPropertyValue("Category", ref category, value);
      }
   }
   public string Subject {
      get {
         return subject;
      }
      set {
         SetPropertyValue("Subject", ref subject, value);
      }
   }
   public string Description {
      get {
         return description;
      }
      set {
         SetPropertyValue("Description", ref description, value);
      }
   }
   ITreeNode ICategorizedItem.Category {
      get {
          return Category;
      }
      set {
         Category = (Category)value;
      }
   }
}
Note

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]
public abstract class Category : BaseObject, ITreeNode {
   [Association("Category-Issues")]
   public XPCollection<Issue> Issues {
      get {
         return GetCollection<Issue>("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; 
      }
   }   
   private void CollectIssuesRecursive(Category issueCategory, XPCollection<Issue> target) {
      target.AddRange(issueCategory.Issues);
      foreach (Category childCategory in issueCategory.Children) {
         CollectIssuesRecursive(childCategory, target);
      }
   }
  //...
}

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.

CategorizedListEditor