从DataTable(C#Windows窗体)向树视图添加子节点
我很难找到一个树状视图来显示儿童笔记 我有一个数据表,其中填充了来自查询的数据 桌子是这样的从DataTable(C#Windows窗体)向树视图添加子节点,c#,winforms,treeview,nodes,C#,Winforms,Treeview,Nodes,我很难找到一个树状视图来显示儿童笔记 我有一个数据表,其中填充了来自查询的数据 桌子是这样的 | ParentOT | ChildOT ------------------- 1 | 2 1 | 3 1 | 4 4 | 5 5 | 6 现在,我需要的是在树视图中对这些数据进行排序 结果必须是这样的(使用相同的表) 我在Windows窗体上尝试了这一点,我唯一能得到的就是树只显示一组child。像这样
| ParentOT | ChildOT
-------------------
1 | 2
1 | 3
1 | 4
4 | 5
5 | 6
现在,我需要的是在树视图中对这些数据进行排序
结果必须是这样的(使用相同的表)
我在Windows窗体上尝试了这一点,我唯一能得到的就是树只显示一组child。像这样
1
|
--2
|
--3
|
--4
|
--5
|
5
|
--6
我试着这样做:
DataTable arbolSub = mssql_cnn.ejecutarSqlSelect(q2);
//Metodo 2: muestra las ot correctamente pero no muestra mas detalle de subOT.
if (trvOTHs.Nodes.Count > 0)
{
trvOTHs.Nodes.Clear();
}
trvOTHs.BeginUpdate();
if (arb.Rows.Count > 0)
{
string otPadre = arb.Rows[0][0].ToString();
int nivel = 0;
trvOTHs.Nodes.Add(arbolSub.Rows[0]["OT Padre"].ToString());
for (int i = 0; i < arbolSub.Rows.Count; i++)
{
//trvOTHs.Nodes.Add(arbolSub.Rows[0]["OT Padre"].ToString());
if (arbolSub.Rows[i]["OT Padre"].ToString() == otPadre)
{
if (trvOTHs.Nodes[nivel].Text == otPadre)
{
trvOTHs.Nodes[nivel].Nodes.Add(arbolSub.Rows[i]["OT Hija"].ToString());
}
}
else
{
otPadre = arbolSub.Rows[i+1]["OT Padre"].ToString();
TreeNode nodo = new TreeNode(otPadre.ToString());
trvOTHs.Nodes.Add(nodo);
nivel++;
}
}
trvOTHs.Nodes[0].Remove();
trvOTHs.ExpandAll();
}
trvOTHs.EndUpdate();
这就成功了。我把它留在这里,以防有人需要。再次感谢。代码中的主要问题是,您没有在树视图中查找要添加的子父级,而是将它们全部添加到主父级下 我对您的代码做了一些更改,希望它能直接工作,或者在您这边做一些小的更改:
if (arb.Rows.Count > 0)
{
TreeNode MainNode = new TreeNode();
string otPadre = arb.Rows[0][0].ToString();
int nivel = 0;
MainNode.Text = otPadre;
trvOTHs.Nodes.Add(MainNode);
for (int i = 0; i < arbolSub.Rows.Count; i++)
{
TreeNode child = new TreeNode();
child.Text = row["OT Hija"].ToString();
if (arbolSub.Rows[i]["OT Padre"].ToString() == otPadre)
{
MainNode.Nodes.Add(child);
}
else
{
FindParent(MainNode, row["OT Padre"].ToString(), child);
}
}
trvOTHs.ExpandAll();
}
<>我会做这样的事情,你应该考虑使用<代码>字典<代码>和<代码> HasSET 以达到最大性能:
//use this extension method for convenience
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);
}
}
}
//usage
treeView1.LoadFromDataTable(yourDataTable);
//为了方便起见,请使用此扩展方法
公共静态类TreeViewExtension{
公共静态void LoadFromDataTable(此树视图tv,DataTable dt){
var parentNodes=dt.AsEnumerable()
.GroupBy(行=>(字符串)行[0])
.ToDictionary(g=>g.Key,value=>value.Select(x=>(string)x[1]);
堆栈查找=新堆栈();
HashSet removedKeys=新HashSet();
foreach(parentNodes中的var节点){
如果(removedKeys.Contains(node.Key))继续;
TreeNode tNode=新的TreeNode(node.Key);
Push(新的KeyValuePair(tNode,node.Value));
而(lookIn.Count>0){
var nodes=lookIn.Pop();
foreach(节点中的变量n.Value){
数不清的孩子;
TreeNode childNode=新的TreeNode(n);
nodes.Key.nodes.Add(childNode);
if(parentNodes.TryGetValue(n,out子项)){
Push(新的KeyValuePair(childNode,children));
移除的密钥。添加(n);
}
}
}
添加(tNode);
}
}
}
//用法
treeView1.LoadFromDataTable(yourDataTable);
注意输入的
数据表
应包含您在问题中发布的数据不需要其他类型的子数据表谢谢回复。我最终解决了这个问题,使用了一位朋友提出的想法,并使用了@Mohammad abumazen建议的解决方案
我最终递归地使用了两种方法:
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["OTHija"].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);
}
}
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["OTHija"].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);
}
}
这就成功了。我把它留在这里,以防有人需要。再次感谢
//use this extension method for convenience
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);
}
}
}
//usage
treeView1.LoadFromDataTable(yourDataTable);
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["OTHija"].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);
}
}