我正在尝试使用foreach循环创建树视图节点。我有2个数据表,当前正在通过foreach循环运行以获取行。我的第一个foreach循环成功地将第一个数据表行放入树视图节点。问题是将第二个数据表行放入每个父节点。
第一个数据表的结构是:
job |suffix
J000027399 0
J000027399 1
J000027399 2
J000027399 3
J000027399 4
J000027399 5
第二个表结构是:
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
我需要像这样填充树节点:
0
10
20
30
1
10
20
2
10
3
10
4
10
20
5
10
父节点基于第一数据表,子节点基于第二数据表。
到目前为止是我的代码
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.SuspendLayout();
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.SuspendLayout();
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();
}