Цикл в цикле
Суть: нужно организовать TreeView. Имеется БД с некоторым количеством записей. Записи, соответственно, указывают имя узла, ID, TopID (под каким находится узлом). Поковыряв немного на коленке, пришел к такому решению:
Код:
private void LoadTreeview()
{
LeftMenuTree.Nodes.Clear();
// This code fills a DataTable with an SQL Query
DBConn db = new DBConn();
DataSet ds = new DataSet();
ds = db.cmd("SELECT * FROM KB_TreeNodes");
DataTable table = new DataTable();
table = ds.Tables[0];
DataRow[] top = null;
top = table.Select("TOPID = 0");
//
// This is the first node in the view.
//
for (int i = 0; i < top.Length; i++)
{
TreeNode treeNode = new TreeNode();
treeNode.Name = top[i]["ID"].ToString();
treeNode.Text = top[i]["Name"].ToString();
DataRow[] under = null;
under = table.Select("TOPID = " + top[i]["ID"].ToString());
if (under.Length > 0)
{
for (int u = 0; u < under.Length; u++)
{
TreeNode child = new TreeNode();
child.Name = under[u]["ID"].ToString();
child.Text = under[u]["Name"].ToString();
treeNode.Nodes.Add(child);
}
}
under = null;
LeftMenuTree.Nodes.Add(treeNode);
}
top = null;
}
{
LeftMenuTree.Nodes.Clear();
// This code fills a DataTable with an SQL Query
DBConn db = new DBConn();
DataSet ds = new DataSet();
ds = db.cmd("SELECT * FROM KB_TreeNodes");
DataTable table = new DataTable();
table = ds.Tables[0];
DataRow[] top = null;
top = table.Select("TOPID = 0");
//
// This is the first node in the view.
//
for (int i = 0; i < top.Length; i++)
{
TreeNode treeNode = new TreeNode();
treeNode.Name = top[i]["ID"].ToString();
treeNode.Text = top[i]["Name"].ToString();
DataRow[] under = null;
under = table.Select("TOPID = " + top[i]["ID"].ToString());
if (under.Length > 0)
{
for (int u = 0; u < under.Length; u++)
{
TreeNode child = new TreeNode();
child.Name = under[u]["ID"].ToString();
child.Text = under[u]["Name"].ToString();
treeNode.Nodes.Add(child);
}
}
under = null;
LeftMenuTree.Nodes.Add(treeNode);
}
top = null;
}
Собственно работает, но вопрос в том, что хочется больше чем два уровня вложения. Единственное, что приходит в голову, это цикл внутри цикла, внутри цикла... и т.д. Но неизвестно заранее сколько будет узлов. Можно, конечно ограничить глубину дерева, но не хотелось бы.
Вопрос: как сделать дерево неограниченной глубины (по возможности), и как можно менее варварским методом?
задай поиск по ключевому слову - дерево в БД - и обрящешь.
как минимум несколько человек давали рецепты на эту тему - в том числе и я
После "изливания души", перекура, и покушать пришел к следующему:
сначала создаем основные (главные/нулевые) ноды, а потом, исключив нулевые ноды проходимся по списку, ищем нужные ноды в готовом дереве, и уже туда присоединяем. Получилась такая ересь:
Код:
private void LoadTreeview()
{
LeftMenuTree.Nodes.Clear();
DBConn db = new DBConn();
DataSet ds = new DataSet();
ds = db.cmd("SELECT * FROM KB_TreeNodes WHERE TOPID = 0");
DataTable table = new DataTable();
table = ds.Tables[0];
DataRow[] top = null;
top = table.Select();
for (int i = 0; i < top.Length; i++)
{
TreeNode treeNode = new TreeNode();
treeNode.Name = top[i]["ID"].ToString();
treeNode.Text = top[i]["Name"].ToString();
LeftMenuTree.Nodes.Add(treeNode);
}
top = null;
ds.Clear();
table.Clear();
}
private void childNodes()
{
DBConn db = new DBConn();
DataSet ds = new DataSet();
ds = db.cmd("SELECT * FROM KB_TreeNodes WHERE TOPID != 0");
DataTable table = new DataTable();
table = ds.Tables[0];
DataRow[] top = null;
top = table.Select();
for (int x = 0; x < table.Rows.Count; x++)
{
TreeNode[] tn = LeftMenuTree.Nodes.Find(top[x]["TOPID"].ToString(), true);
for (int i = 0; i < tn.Length; i++)
{
LeftMenuTree.SelectedNode = tn[0];
TreeNode treeNode = new TreeNode();
treeNode.Name = top[x]["ID"].ToString();
treeNode.Text = top[x]["Name"].ToString();
LeftMenuTree.SelectedNode.Nodes.Add(treeNode);
}
}
top = null;
ds.Clear();
table.Clear();
}
{
LeftMenuTree.Nodes.Clear();
DBConn db = new DBConn();
DataSet ds = new DataSet();
ds = db.cmd("SELECT * FROM KB_TreeNodes WHERE TOPID = 0");
DataTable table = new DataTable();
table = ds.Tables[0];
DataRow[] top = null;
top = table.Select();
for (int i = 0; i < top.Length; i++)
{
TreeNode treeNode = new TreeNode();
treeNode.Name = top[i]["ID"].ToString();
treeNode.Text = top[i]["Name"].ToString();
LeftMenuTree.Nodes.Add(treeNode);
}
top = null;
ds.Clear();
table.Clear();
}
private void childNodes()
{
DBConn db = new DBConn();
DataSet ds = new DataSet();
ds = db.cmd("SELECT * FROM KB_TreeNodes WHERE TOPID != 0");
DataTable table = new DataTable();
table = ds.Tables[0];
DataRow[] top = null;
top = table.Select();
for (int x = 0; x < table.Rows.Count; x++)
{
TreeNode[] tn = LeftMenuTree.Nodes.Find(top[x]["TOPID"].ToString(), true);
for (int i = 0; i < tn.Length; i++)
{
LeftMenuTree.SelectedNode = tn[0];
TreeNode treeNode = new TreeNode();
treeNode.Name = top[x]["ID"].ToString();
treeNode.Text = top[x]["Name"].ToString();
LeftMenuTree.SelectedNode.Nodes.Add(treeNode);
}
}
top = null;
ds.Clear();
table.Clear();
}