views:

100

answers:

3

I have a TreeView control in a Windows Forms application that is displaying my own subclass of TreeNode. I need to display a number along with each node's text indicating its position in the tree, like 1 for the root, 1.1 for its first child, 1.2 for its second child, etc. I'm using C# with .NET 2.0

The best that I can come up with is, after the tree is built, go to each node, recursively find the parent and append the parent's sibling number to the front of the node's text until you reach the root.

+1  A: 

You could subclass TreeNode, add properties and overrides as necessary.

Or you could assign numbers Tag property as you build the tree. The algorithm will depend on how you build the tree (top down vs bottom up etc).

More explicit info (code) would help formulate a more explicit answer.

update after OP comment:

Sorry, I was misremembering; you need to override TreeView instead. Something like

public class MyTreeView : System.Windows.Forms.TreeView
{
  // ...

    protected override void OnDrawNode(DrawTreeNodeEventArgs e)
    {
        if (e.Node.Tag != null)
        {
            if (e.Node.Tag.GetType() == typeof(MyDataObject))
            {
                MyDataObject data = (MyDataObject)e.Node.Tag;
                e.Node.Name = data.Number + ". " + data.Name;
            }
        }
     }
}
BioBuckyBall
The tree is built by top-down recursion, so at the time that each node is created its own position in the tree is known.I've already subclassed TreeNode to add more properties, so what would I need to override to change the way that it is displayed in the TreeView? If I used one of the path-building algorithms below I only need to append the result to the node's name when it is rendered.
Travis Christian
A: 

Write a recursive function to traverse the tree, passing in to each node the parent's number to use as a prefix.

void Traverse(TreeNode node, string parentNumber)
{
    string nodeNumber = parentNumber + node.Index.ToString();
    node.Text = nodeNumber;
    string prefix = nodeNumber + ".";
    foreach (TreeNode childNode in node.Nodes)
        Traverse(childNode, prefix);
}

Call this on the root TreeNode with the empty string as the parentNumber string.

bbudge
A: 

You could use an extension, so you can reuse the code, and get the path any time you want.

Is bad implemented, but gives you an idea.

public static class Extensions
    {
        public static string GetPosition(this TreeNode node)
        {
            string Result = "";
            BuildPath(node, ref Result);
            return Result.TrimStart('.');
        }
        private static void BuildPath(TreeNode node,ref string path)
        {
            path = "." + node.Index + path;
            if (node.Parent != null) 
                BuildPath(node.Parent, ref path);
        }
    }
Fraga