-1

今週の初めまでに、TreeView に子が表示されないという問題がありました。すべてが再帰によって解決されました。ただし、予期しない新しい問題が発生しました。私が使用しているメソッドは、特定の DataTables で重複したノードを取得しています。

2 つの列のこの 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

そのツリービューを表示しようとすると、正しいツリービューが表示されますが、5 回連続して表示されます (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 に答える