I have a table with 3 columns, ID, Name and ParentID. The ID column contains running number which also serves as the primary key. ID will also be the node's Name properties. Name column contain string that will be the treenode's Text attribute, while ParentID is a column contains the node's parent ID.
This is how my table looks like:
ID Name ParentID
======================
1 A 0
2 A1 1
3 B 0
4 C 0
5 A2 1
6 B1 3
This table shows that node A is the parent node for node A1 and A2. ParentID equals to "0" means that the node's parent is the root node (hardcoded). E.g., Node A, B and C are root node's children.
I sort the rows by ParentID prior to populating the treeview. I populate the tree view using these two methods (TreeNode node here is the childnode that is being populated into the tree):
private void SearchParent(TreeView tree, String parentID, TreeNode node)
{
// Post: call TraverseParent method to search parent
TreeNodeCollection collection = tree.Nodes;
// Search parent recursively
foreach (TreeNode n in collection)
{
TraverseParent(n, parentID, node);
}
}
private void TraverseParent(TreeNode potentialParent, String parentID, TreeNode node)
{
// Post: search for parent. When parent is found add child to parent
// am i the parent that you're looking for?
if (parentID.CompareTo(potentialParent.Name) == 0)
{
// found me! i'm your parent!
// add child to parent
potentialParent.Nodes.Add(node);
// update that the parent for child has been found
parentFound = true;
}
else
{
// i'm not your parent
// continue to look for parent recursively
foreach (TreeNode n in potentialParent.Nodes)
{
TraverseParent(n, parentID, node);
}
}
}
All is well until I drag-and-drop the nodes by making node A the child of node C and commit the changes to the database.
Now my database table looks like this:
ID Name ParentID
======================
1 A 4
2 A1 1
3 B 0
4 C 0
5 A2 1
6 B1 3
The next time I run the application, it fails to populate node A1 and A2 into the tree because it could not find their parents. This is because when I sort the rows based on ParentID prior to populating the treeview, the rows are sorted like this:
ID Name ParentID
======================
3 B 0
4 C 0
2 A1 1
5 A2 1
6 B1 3
1 A 4
This way, my application will try to populate A1 and A2 nodes into the tree even before node A is created. Therefore the application could not find the parent for node A1 and A2.
Hence, can anyone tell me a way to fix this bug or is there a better way to dynamically populate a treeview?
Thanks.
You should use recursion to fill it.
The promised example:
public partial class Form1 : Form
{
private class ItemInfo
{
public int ID;
public int ParentID;
public string Name;
}
public Form1()
{
InitializeComponent();
FillTreeView();
}
private void FillTreeView()
{
var items = new List<ItemInfo>()
{
new ItemInfo(){ID = 1, ParentID = 4, Name = "A"},
new ItemInfo(){ID = 2, ParentID = 1, Name = "A1"},
new ItemInfo(){ID = 3, ParentID = 0, Name = "B"},
new ItemInfo(){ID = 4, ParentID = 0, Name = "C"},
new ItemInfo(){ID = 5, ParentID = 1, Name = "A2"},
new ItemInfo(){ID = 6, ParentID = 3, Name = "B1"},
};
FillNode(items, null);
}
private void FillNode(List<ItemInfo> items, TreeNode node)
{
var parentID = node != null
? (int)node.Tag
: 0;
var nodesCollection = node != null
? node.Nodes
: treeView1.Nodes;
foreach (var item in items.Where(i => i.ParentID == parentID))
{
var newNode = nodesCollection.Add(item.Name, item.Name);
newNode.Tag = item.ID;
FillNode(items, newNode);
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With