C#treeview获取重复节点

时间:2013-10-25 21:07:04

标签: c# winforms treeview

到本周初,我遇到了TreeView无法显示子项的问题。一切都通过递归得到了解决。但是,出现了一个新的意外问题:我正在使用的方法是在某些特定的DataTable上获得重复的节点。

拥有两列的DataTable:

ParentOT    ChildOT
20120601    20120602
20120601    20120603
20120601    20120604
20120601    20120611
20120601    20120612
20120602    20120605
20120602    20120606
20120602    20120607
20120602    20120608
20120602    20120610
20120603    20120607
20120603    20120608
20120603    20120609

如果我尝试显示其Treeview,我会得到正确的树视图,但连续五次(父项在parentOT记录中显示为父视图的时间)。

方法是这些:

 private TreeView cargarOtPadres(TreeView trv, int otPadre, DataTable datos)
    {
        if (datos.Rows.Count > 0)
        { 
            foreach (DataRow dr in datos.Select("OTPadre="+ otPadre))
            {
                TreeNode nodoPadre = new TreeNode();
                nodoPadre.Text = dr["OTPadre"].ToString();
                trv.Nodes.Add(nodoPadre);
                cargarSubOts(ref nodoPadre, int.Parse(dr["OTPadre"].ToString()), datos);
            }
        }
        return trv;
    }

    private void cargarSubOts(ref TreeNode nodoPadre, int otPadre, DataTable datos)
    {
        DataRow[] otHijas = datos.Select("OTPadre=" + otPadre);
        foreach (DataRow drow in otHijas)
        {
            TreeNode hija = new TreeNode();
            hija.Text = drow["OTHija"].ToString();
            nodoPadre.Nodes.Add(hija);
            cargarSubOts(ref hija, int.Parse(drow["OTHija"].ToString()), datos);
        }
    }

只有1个出色的父级表只有1次出现,它的效果很好。如何防止TreeView重复?

1 个答案:

答案 0 :(得分:0)

为了完成,我会留下答案。这个解决方案来自@King King

public static class TreeViewExtension
{
    public static void LoadFromDataTable(this TreeView tv, DataTable dt)
    {
        var parentNodes = dt.AsEnumerable()
                            .GroupBy(row => (string)row[0])
                            .ToDictionary(g => g.Key, value => value.Select(x => (string)x[1]));
        Stack<KeyValuePair<TreeNode, IEnumerable<string>>> lookIn = new Stack<KeyValuePair<TreeNode, IEnumerable<string>>>();
        HashSet<string> removedKeys = new HashSet<string>();
        foreach (var node in parentNodes)
        {
            if (removedKeys.Contains(node.Key)) continue;
            TreeNode tNode = new TreeNode(node.Key);
            lookIn.Push(new KeyValuePair<TreeNode, IEnumerable<string>>(tNode, node.Value));
            while (lookIn.Count > 0)
            {
                var nodes = lookIn.Pop();
                foreach (var n in nodes.Value)
                {
                    IEnumerable<string> children;
                    TreeNode childNode = new TreeNode(n);
                    nodes.Key.Nodes.Add(childNode);
                    if (parentNodes.TryGetValue(n, out children))
                    {
                        lookIn.Push(new KeyValuePair<TreeNode, IEnumerable<string>>(childNode, children));
                        removedKeys.Add(n);
                    }
                }
            }
            tv.Nodes.Add(tNode);
        }
    }
}

您创建此类

之后就像这样使用。

treeView1.LoadFromDataTable(DataTable);

请务必将其与String类型DataTable一起使用。如果你有一个int类型表,你可以这样做:

DataTable stringDataTable = intDataTable.Clone();
           stringDataTable.Columns[0].DataType = typeof(string);
           stringDataTable.Columns[1].DataType = typeof(string);

            foreach (DataRow dr in intDataTable.Rows)
            {
                stringDataTable.ImportRow(dr);
            }

treeView1.LoadFromDataTable(stringDataTable);