6

我有一个包含 3 列、ID、Name 和 ParentID 的表。ID 列包含运行号,它也用作主键。ID 也将是节点的名称属性。Name 列包含将成为树节点的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 的父节点。

因此,任何人都可以告诉我解决此错误的方法还是有更好的方法来动态填充树视图?

谢谢。

4

1 回答 1

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);
            }
        }
    }
于 2012-05-30T10:36:23.220 回答