我有一个包含3列,ID,Name和ParentID的表。 ID列包含运行编号,该编号也用作主键。 ID也将是节点的名称属性。 Name列包含将成为treenode的 Text 属性的字符串,而ParentID是包含节点的父ID的列。
这就是我的表格:
ID Name ParentID
======================
1 A 0
2 A1 1
3 B 0
4 C 0
5 A2 1
6 B1 3
此表显示节点A是节点A1和A2的父节点。 ParentID等于“0”表示节点的父节点是根节点(硬编码)。例如,节点A,B和C是根节点的子节点。
在填充树视图之前,我按ParentID对行进行排序。我使用这两种方法填充树视图(这里的TreeNode节点是填充到树中的子节点):
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);
}
}
}
一切顺利,直到我通过使节点A成为节点C的子节点并将更改提交到数据库来拖放节点。
现在我的数据库表如下所示:
ID Name ParentID
======================
1 A 4
2 A1 1
3 B 0
4 C 0
5 A2 1
6 B1 3
下次运行应用程序时,它无法将节点A1和A2填充到树中,因为找不到它们的父节点。这是因为当我在填充树视图之前根据ParentID对行进行排序时,行的排序方式如下:
ID Name ParentID
======================
3 B 0
4 C 0
2 A1 1
5 A2 1
6 B1 3
1 A 4
这样,我的应用程序将尝试在创建节点A之前将A1和A2节点填充到树中。因此,应用程序找不到节点A1和A2的父节点。
因此,任何人都可以告诉我修复此错误的方法,还是有更好的方法来动态填充树视图?
感谢。
答案 0 :(得分:15)
您应该使用递归来填充它。
承诺的例子:
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);
}
}
}