How to get Text from all Parent Nodes of a Node in TreeView?

Maybe I couldn't explain well, but this should explain: I have a int field called getParentNode(TreeNode) to get how many parent it has (e.g if there is 2 nodes below node, count will be 2) And I have a List field called getParentNames(TreeNode) that returns all of the parent's names.

getParentCount:

int getParentCount(TreeNode node)
{
    int count = 1;
    while (node.Parent != null)
    {
        count++;
        node = node.Parent;
    }
    return count;
}

getParentsNames:

List<string> getParentNames(TreeNode node)
{
    List<string> list = new List<string>();
    for (int i = 0; i < getParentCount(node); i++)
    {
        //i = 1 : list.Add(node.Parent.Text);
        //i = 2 : list.Add(node.Parent.Parent.Text);
        //i = 3 ...
    }
    return list;
}

Do I need to check if (i == 0) (I don't want to write manually because number can be anything) or something? Regards.

Upvotes: 1

Views: 3364

Answers (3)

Reza Aghaei
Reza Aghaei

Reputation: 125342

You can use either of these options:

  • Split FullPath of node by PathSeparator of tree
  • Ancestors and AncestorsAndSelf sxtension methods


Split FullPath of node by PathSeparator of tree

You can use FullPath property of the TreeNode and split the result using PathSeparator property of TreeView. For example:

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    var ancestorsAndSelf = e.Node.FullPath.Split(treeView1.PathSeparator.ToCharArray());
}

Ancestors and AncestorsAndSelf sxtension methods

Also you can get all ancestors of a TreeNode. You can simply use a while loop to go up using node.Parent while the parent is not null. I prefer to encapsulate this logic in an extension method and make it more reusable for future. You can create an extension method to return all parent nodes (ancestors) of a node:

using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
public static class TreeViewExtensions
{
    public static List<TreeNode> Ancestors(this TreeNode node)
    {
        return AncestorsInternal(node).Reverse().ToList();
    }
    public static List<TreeNode> AncestorsAndSelf(this TreeNode node)
    {
        return AncestorsInternal(node, true).Reverse().ToList();
    }
    private static IEnumerable<TreeNode> AncestorsInternal(TreeNode node, bool self=false)
    {
        if (self)
            yield return node;
        while (node.Parent != null)
        {
            node = node.Parent;
            yield return node;
        }
    }
}

Usage:

List<TreeNode> ancestors = treeView1.SelectedNode.Ancestors();

You can get text or any other property from ancestors:

List<string> ancestors = treeView1.SelectedNode.Ancestors().Select(x=>x.Text).ToList(); 

Note

JFYI you can use an extension method approach to get all child nodes too. Here I've shared an extension method to to so: Descendants Extension Method.

Upvotes: 1

Anyways, I noticed that I need to use while loop:

List<string> getParentNames(TreeNode node)
    {
        List<string> list = new List<string>();
        int count = getParentCount(node);
        int index = 0;
        TreeNode parent = node;
        while (index < count)
        {
            if (parent != null)
            {
                index++;
                list.Add(parent.Text);
                parent = parent.Parent;
            }
        }
        return list;
    }

Upvotes: 0

Paolo Ursini
Paolo Ursini

Reputation: 280

why don't you use the node.FullPath counting the TreeView.PathSeparator char? Something like

char ps = Convert.ToChar( TreeView1.PathSeparator);
int nCount = selectedNode.FullPath.Split(ps).Length;

Upvotes: 1

Related Questions