0

我在 SQL Server 中有一个表,我想将它加载到 WPF 中的树视图

类别 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"]);
            }

        }
    }
4

1 回答 1

0

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

当你说

DataTable dtb = dt;

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

由于桌子很小,您可能会逃脱

DataTable dtb = dt.Clone();

这将制作表的副本,而不仅仅是同一张表的别名。

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

于 2013-10-17T16:05:38.113 回答