-1

到本周初,我遇到了 TreeView 不显示子项的问题。一切都是通过递归解决的。然而,出现了一个新的和意想不到的问题:我使用的方法是在某些特定的 DataTables 上获取重复的节点。

有这个两列的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

如果我尝试显示它的树视图,我会得到正确的树视图,但连续五次(父项在 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 重复?

4

1 回答 1

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);
于 2013-10-29T12:41:57.997 回答