Building a tree recursively is a difficult task even for an experienced programmer. I understand that I'm a little late to the party on this issue, given that it was originally published in March 2011. Better late than never?
One important factor when creating a tree is simply to make sure your dataset is properly formatted. You just need a way to associate a parent with a child. Once the association is clearly defined, you can start coding the solution. I decided to use a simple format:
ParentId ChildId 1 2 1 3 2 4 3 5
Etc.
Once this relationship is established, I developed a recursive method for iterating over the dataset to build the tree.
First, I identify all the parent nodes and store them in the collection, giving them each unique identifier using a combination of the parent identifier and the child identifier:
private void IdentifyParentNodes() { SortedList<string, MyTreeNode> newParentNodes = new SortedList<string,MyTreeNode>(); Dictionary<string, string> parents = new Dictionary<string, string>(); foreach (MyTreeNode oParent in MyTreeDataSource.Values) { if (!parents.ContainsValue(oParent.ParentId)) { parents.Add(oParent.ParentId + "." + oParent.ChildId, oParent.ParentId); newParentNodes.Add(oParent.ParentId + "." + oParent.ChildId, oParent); } } this._parentNodes = newParentNodes; }
Then the root invocation method will go through the parents and invoke the recursive method to build the tree:
Recursive Method:
private void RecursivelyBuildTree(MyTreeNode node) { int nodePosition = 0; _renderedTree.Append(FormatNode(MyTreeNodeType.Parent, node, 0)); _renderedTree.Append(NodeContainer("open", node.ParentId)); foreach (MyTreeNode child in GetChildren(node.ParentId).Values) { nodePosition++; if (IsParent(child.ChildId)) { RecursivelyBuildTree(child); } else { _renderedTree.Append(FormatNode(MyTreeNodeType.Leaf, child, nodePosition)); } } _renderedTree.Append(NodeContainer("close", node.ParentId)); }
Method used to get the children of the parent:
private SortedList<string, MyTreeNode> GetChildren(string parentId) { SortedList<string, MyTreeNode> childNodes = new SortedList<string, MyTreeNode>(); foreach (MyTreeNode node in this.MyTreeDataSource.Values) { if (node.ParentId == parentId) { childNodes.Add(node.ParentId + node.ChildId, node); } } return childNodes; }
Not that sophisticated or elegant, but he did his job. It was written in 2007, so this is old code, but it still works. :-) Hope this helps.