如何使用 Foreach 循环将数据从数据 table 节点迭代到树节点

How can you use a Foreach loop to iterate data into treenode from data table nodes

我正在尝试使用 foreach 循环创建树视图节点。我有 2 个数据 table 当前正在 运行 通过 foreach 循环来抓取行。我的第一个 foreach 循环成功地将第一个数据 table 行放入树视图节点。问题是将第二个数据 table 行放入每个父节点。

第一个数据table的结构是:

job       |suffix
J000027399   0
J000027399   1
J000027399   2
J000027399   3
J000027399   4
J000027399   5

第二个table结构是:

job       |suffix|operNum
J000027399  0        10
J000027399  0        20
J000027399  0        30
J000027399  1        10
J000027399  1        20
J000027399  2        10
J000027399  3        10
J000027399  4        10
J000027399  4        20
J000027399  5        10

第三个table结构是:

job       |suffix|operNum|seq|item
J000027399  0        30    1  item_1
J000027399  0        30    2  item_2
J000027399  0        30    3  item_3
J000027399  0        30    4  item_4
J000027399  1        10    1  item_1
J000027399  1        10    2  item_2
J000027399  1        10    3  item_3
J000027399  1        20    1  item_1
J000027399  1        20    2  item_2
J000027399  2        10    1  item_1
J000027399  3        10    1  item_1
J000027399  4        10    1  item_1
J000027399  4        10    2  item_2
J000027399  4        20    1  item_1
J000027399  5        10    1  item_1

我需要像这样填充树节点:

0 
 10
 20
 30
   1
   2
   3
   4
1
 10
   1
   2
   3
 20
   1
   2
2
 10
   1
3
 10
   1
4
 10
   1
   2
 20
   1
5
 10
   1

父节点基于第一个数据table后缀,子节点基于第二个数据table opernum,第三个数据table基于seq在每个后缀节点的每个 opernum 下。

到目前为止,这是我的代码

using (SqlDataAdapter jobAdapter = new SqlDataAdapter(cmd))
{            
    DataTable dtJ = new DataTable();
    jobAdapter.Fill(dtJ);

    foreach (DataRow jRow in dtJ.Rows)
    {
        tvBomView.Nodes.Add("job", jRow["Suffix"].ToString());
    }

    SqlCommand cmdStageTwo = new SqlCommand("dbo.CHS_Bom_View_Grab_JobRoute", conn);
    cmdStageTwo.CommandType = CommandType.StoredProcedure;
    cmdStageTwo.Parameters.Add("@Job", SqlDbType.NVarChar, 10).Value = txtJob.Text;

    using (SqlDataAdapter jobRouteAdapter = new SqlDataAdapter(cmdStageTwo))
    {
        DataTable dtJR = new DataTable();
        jobRouteAdapter.Fill(dtJR);

        foreach (TreeNode node in tvBomView.Nodes)
        {
            foreach (DataRow jrRow in dtJR.Rows)
            {
                if (node.Text != jrRow["Suffix"].ToString())
                {
                    break;
                }
                else if (node.Text == jrRow["Suffix"].ToString())
                {
                    tvBomView.Nodes["job"].Nodes.Add("oper", "Oper: " + 
                        jrRow["OperNum"].ToString());
                }
            }
        }
    }
}

尝试以下操作:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            DataTable dt = new DataTable();
            dt.Columns.Add("job", typeof(string));
            dt.Columns.Add("suffix", typeof(int));
            dt.Columns.Add("operNum", typeof(int));

            dt.Rows.Add(new object[] { "J000027399", 0, 10});
            dt.Rows.Add(new object[] { "J000027399", 0, 20});
            dt.Rows.Add(new object[] { "J000027399", 0, 30});
            dt.Rows.Add(new object[] { "J000027399", 1, 10});
            dt.Rows.Add(new object[] { "J000027399", 1, 20});
            dt.Rows.Add(new object[] { "J000027399", 2, 10});
            dt.Rows.Add(new object[] { "J000027399", 3, 10});
            dt.Rows.Add(new object[] { "J000027399", 4, 10});
            dt.Rows.Add(new object[] { "J000027399", 4, 20});
            dt.Rows.Add(new object[] { "J000027399", 5, 10});

            var groups = dt.AsEnumerable()
                .OrderBy(x => x.Field<int>("suffix"))
                .ThenBy(x => x.Field<int>("operNum"))
                .GroupBy(x => x.Field<int>("suffix"));

            foreach (var group in groups)
            {
                TreeNode node = new TreeNode(group.Key.ToString());

                treeView1.Nodes.Add(node);
                foreach (DataRow row in group)
                {
                    node.Nodes.Add(row.Field<int>("operNum").ToString());
                }

            }
            treeView1.ExpandAll();
        }
    }
}

您可以同时加载 DataTable-s 并将它们与 TreeView 一起传递给创建树的方法:

{
//The method where you call dtJ and dtJR from the database:
ToTreeView(tvBomView, dtj, dtJR);
}

ToTreeView(..)方法:

private void ToTreeView(TreeView tv, DataTable dt1, DataTable dt2)
{
    tv.BeginUpdate();
    tv.Nodes.Clear();

    //Create a temp IEnumerable of anonymous type:
    var items = dt1.Rows.Cast<DataRow>()
        .Select(x => new
        {
            Parent = x,
            Children = dt2.Rows.Cast<DataRow>()
            .Where(y => y["suffix"].ToString() == x["suffix"].ToString())
        });

    foreach(var item in items)
    {
        var parentNode = tv.Nodes.Add("job", item.Parent["suffix"].ToString());

        foreach(var child in item.Children)
        {
            parentNode.Nodes.Add("oper", $"Oper: {child["operNum"].ToString()}");
        }
    }

    tv.EndUpdate();
}

或者只是:

private void ToTreeView(TreeView tv, DataTable dt1, DataTable dt2)
{
    tv.BeginUpdate();
    tv.Nodes.Clear();

    dt1.Rows.Cast<DataRow>()
        .ToList()
        .ForEach(x =>
        {
            var p = tv.Nodes.Add("job", x["Suffix"].ToString());
            dt2.Rows.Cast<DataRow>()
            .Where(y => x["Suffix"].ToString() == y["Suffix"].ToString())
            .ToList()
            .ForEach(y => p.Nodes.Add("oper", $"Oper: {y["operNum"].ToString()}"));
        });

    tv.EndUpdate();
}

编辑:3 表版本

private void ToTreeView(TreeView tv, DataTable dt1, DataTable dt2, DataTable dt3)
{
    tv.BeginUpdate();
    tv.Nodes.Clear();

    dt1.Rows.Cast<DataRow>()
        .ToList()
        .ForEach(x =>
        {
            var p = tv.Nodes.Add("job", x["suffix"].ToString());
            dt2.Rows.Cast<DataRow>()
            .Where(y => x["suffix"].ToString() == y["suffix"].ToString())
            .ToList()
            .ForEach(y =>
            {
                var c = p.Nodes.Add("oper", $"Oper: {y["operNum"].ToString()}");
                dt3.Rows.Cast<DataRow>()
                .Where(z => z["suffix"].ToString() == y["suffix"].ToString() &&
                z["operNum"].ToString() == y["operNum"].ToString())
                .ToList()
                .ForEach(n => c.Nodes.Add("seq", $"Seq: {n["seq"].ToString()}"));
            });
        });

    tv.EndUpdate();
}

请将此视为一种快速而肮脏的解决方法,并考虑评论中提到的内容。查看下面的相关帖子。

Related

Populate TreeView from DataTable
Populate WinForms TreeView from DataTable
Populate TreeView from Database using C#