Search code examples
c#.netwpfrecursionobservablecollection

Get item of recursive observablecollection


I have a TreeITem class with a observablecollection.

/// <summary>
/// Item class to generate a tree view of the queues and topics from the service bus.
/// </summary>
public class TreeItem
{
    /// <summary>
    /// The whole namespace tree
    /// </summary>
    public static ObservableCollection<TreeItem> Tree { get; set; }

    //TreeItem properties
    public string Name { get; set; }
    public ObservableCollection<TreeItem> Items { get; set; }
    .........

If I create a tree structure I do the following:

            //Get queues and topics
            TreeItem namespaceTree = new TreeItem() { Name = namespaceManager.Address.ToString() };
            TreeItem queuesTree = GetQueues(namespaceManager.GetQueues());

            //Get queues and topics
            TreeItem namespaceTree = new TreeItem() { Name = namespaceManager.Address.ToString() };
            TreeItem queuesTree = GetQueues(namespaceManager.GetQueues());
            TreeItem topicsTree = GetTopics(namespaceManager.GetTopics());         

            //Generate the topic structure.
            namespaceTree.Items.Add(queuesTree);
            namespaceTree.Items.Add(topicsTree);
            Tree.Add(namespaceTree);

If I bind the tree to the tree view everthing works fine but when I want to get a element from the Tree I have a problem. For instance I tried to get a special topic from the Tree it didn't work. I tried it with the following code:

    private TreeItem GetTopicFromTree(ObservableCollection<TreeItem> tree)
    {
        TreeItem treeItem = null;
        foreach(var item in tree)
        {
            if (!item.Name.Equals("topicx"))
                GetTopicFromTree(item.Items);

            else
                treeItem = item;
        }

        return treeItem;
    }

But with the recursion it didn't worked.


Solution

  • Is this what you are trying to do?

    private TreeItem GetTopicFromTree(ObservableCollection<TreeItem> tree)
    {
        foreach(var item in tree.Items)
        {
            var found = GetTopicFromTree(item);
    
            if (found != null)
                return found;
        }
    
        return null;
    }
    

    But TreeItem is not an ObservableCollection, so you'd need a 2nd method of GetTopicFromTree to handle TreeItem.

    private TreeItem GetTopicFromTree(TreeItem tree)
    {
        if (Name.Equals("topicx"))
            return this;
    
        foreach(var item in tree.Items)
        {
            var found = GetTopicFromTree(item);
    
            if (found != null)
                return found;
        }
    
        return null;
    }
    

    Or, perhaps a touch cleaner

    private TreeItem FindTopic(TreeItem node, string name)
    {
        if (node.Name == name)
            return node;
    
        foreach (var child in node.Items)
        {
            var found = FindTopic(child, name);
            if (found != null)
                return found;
        }
    
        return null;
    }