C#中的TreeView递归从SQL Server加载

时间:2013-10-17 15:43:34

标签: c# sql wpf treeview

我在SQL Server中有一个表,我想在WPF中将其加载到treeview

类别ID名称ParentID 1服装0
2娱乐0
3税收...... 1 4电话...... 2
5租... 3
6旅行...... 1
7薪水... 2
8 ABC ... 3
9礼物...... 5
10酷...... 1 11收入...... 4
12塔... 6

我在C#中的代码:

private void LoadTreeView()
    {
        SqlConnection con = new SqlConnection(s);
        SqlCommand comm = new SqlCommand("SELECT * FROM Category", con);
        SqlDataAdapter da = new SqlDataAdapter(comm);
        DataSet ds = new DataSet();
        da.Fill(ds);
        DataTable dt = ds.Tables[0];
        TreeViewItem tvi = new TreeViewItem();
        AddNode(tvi, dt, 0);
        con.Close();
    }

private void AddNode(TreeViewItem tvi, DataTable dt, int node)
    {
        foreach (DataRow row in dt.Rows)
        {
            if ((int)row["ParentID"] == 0)
            {
                tvi = new TreeViewItem();
                tvi.Header = row["Name"];
                treeView.Items.Add(tvi);
                DataTable dtb = dt;
                node = (int)row["CategoryID"];
                dtb.Rows.Remove(row);
                AddNode(tvi, dtb, node);
            }
            else
            {
                int i = 0;

                foreach (DataRow r in dt.Rows)
                {
                    i++;
                    if ((int)r["ParentID"] == node)
                    {
                        TreeViewItem tvi2 = new TreeViewItem();
                        tvi2.Header = r["Name"];
                        tvi.Items.Add(tvi2);
                        DataTable dtb = dt;
                        node = (int)r["CategoryID"];
                        dtb.Rows.Remove(r);
                        if (dtb.Rows.Count == 0)
                            return;
                        AddNode(tvi2, dtb, node);
                    }
                    if (i == dt.Rows.Count)
                        return;
                }
            }
            if (dt.Rows.Count == 0)
                return;
        }
    }

但是在第二个foreach中运行时出错了 System.Data.dll

中发生了未处理的“System.InvalidOperationException”类型异常

其他信息:收集已修改;枚举操作可能不会执行。

我该如何解决?

编辑:我已经修好了。

private void AddNode(TreeViewItem tvi, DataTable dt, int node)
    {
        foreach (DataRow row in dt.Rows)
        {
            if ((int)row["ParentID"] != 0 && (int)row["ParentID"] == node)
            {
                TreeViewItem tvi2 = new TreeViewItem();
                tvi2.Header = row["Name"];
                tvi.Items.Add(tvi2);
                DataTable dt2 = dt.Copy();
                int i = 0;
                for (i = 0; i < dt.Rows.Count - 1; i++)
                {
                    if (row["CategoryID"] == dt.Rows[i]["CategoryID"])
                        break;
                }
                if (dt2.Rows.Count == 1)
                    return;
                dt2.Rows.RemoveAt(i);
                AddNode(tvi2, dt2, (int)row["CategoryID"]);
            }
            else if ((int)row["ParentID"] == 0 && node == 0)
            {
                tvi = new TreeViewItem();
                tvi.Header = row["Name"];
                treeView.Items.Add(tvi);
                DataTable dt2 = dt.Copy();
                int i = 0;
                for (i = 0; i < dt.Rows.Count - 1; i++)
                {
                    if ((int)row["CategoryID"] == (int)dt.Rows[i]["CategoryID"])
                        break;
                }
                if (dt2.Rows.Count == 1)
                    return;
                dt2.Rows.RemoveAt(i);
                AddNode(tvi, dt2, (int)row["CategoryID"]);
            }

        }
    }

1 个答案:

答案 0 :(得分:0)

您正在修改dt.Rows循环中正在操作的数据表。

当你说

DataTable dtb = dt;

它正在创建另一个指向同一个表的链接,它不会创建新表。因此,当你修改dtb时,你也在修改dt(基本上dt和dtb是同一个表的两个名字。)

由于表格相当小,您可以使用

DataTable dtb = dt.Clone();

这将创建表的副本,而不仅仅是同一个表的别名。

但是,我不明白你为什么要从dtb中删除一行。由于您在本地范围内,并且未在范围内再次使用该表,因此这似乎是无意义的操作。由于dtb在原始代码中仅仅是一个别名,因此您可以在dt上使用dtb执行完全相同的结果。