Введение
На многих форумах посвященных ASP .Net технологии поднимался вопрос
работы с TreeView и его динамического заполнения, но решения нужного мне
я так и не нашел. Хочу представить свое решение данной проблемы.
Создание таблицы для хранения дерева (на примере дерева
департаментов)
CREATE TABLE DEPARTMENT (
ID NUMBER NOT NULL,
PARENTID NUMBER NOT NULL,
NAME VARCHAR2(100) NOT NULL,
constraint DEPARTMENT_PK primary key (ID) );
ID - уникальный ключ.
PARENTID - ссылка на родительский департамент .
NAME - название департамента.
Обязательное условие ID рутовой ноды должно быть 0.
Реализация
Далее хочу привести код за кодом будут комментарии.
protected Microsoft.Web.UI.WebControls.TreeView TreeOfStaff;
public void FillTree()
{
string sql="SELECT id, name, parentid FROM Department "+
"ORDER BY ID"
using(OleDbDataAdapter Tree=new OleDbDataAdapter(sql,new
OleDbConnection(ConectionString.ConnectionString)))
{
Tree.SelectCommand.Connection.Open();
OleDbDataReader Node=
Tree.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection);
SortedList Nodes = new SortedList();
TreeNode RootNode = new TreeNode();
using(Node)
{
Node.Read();
RootNode.Text = Node["NAME"].ToString();
Nodes.Add(int.Parse(Node["ID"].ToString()),RootNode);
while(Node.Read())
{
TreeNode ParentNode = new TreeNode();
ParentNode.Text=Node["NAME"].ToString();
ParentNode.ID=Node["PARENTID"].ToString();
Nodes.Add(int.Parse(Node["ID"].ToString()),ParentNode);
}
Node.Close();
for (int i=1;i<Nodes.Count;i++)
{
if(int.Parse(((TreeNode)Nodes.GetByIndex(i)).ID)!=0)
{
int lvl = int.Parse(((TreeNode)Nodes.GetByIndex(i)).ID);
TreeNode nNode = ((TreeNode)Nodes[lvl]);
nNode.Nodes.Add(((TreeNode)Nodes.GetByIndex(i)));
}
}
}
TreeOfStaff.Nodes.Add((TreeNode)Nodes.GetByIndex(0));
}
Шаг первый, извлекаем все ноды из таблицы и помещаем их в
OleDbDataReader.
string sql="SELECT id, name, parentid FROM Department "+
"ORDER BY ID"
using(OleDbDataAdapter Tree=new OleDbDataAdapter(sql,new
OleDbConnection(ConectionString.ConnectionString)))
{
Tree.SelectCommand.Connection.Open();
OleDbDataReader Node=
Tree.SelectCommand.ExecuteReader(CommandBehavior.CloseConnection);
Далее объявляем
SortedList Nodes = new SortedList();
в нем будем хранить все ноды нашего дерева.
После этого можно добавлять корень дерева (Root)
TreeNode RootNode = new TreeNode();
using(Node)
{
Node.Read();
RootNode.Text = Node["NAME"].ToString();
Далее добавляем Root в наш SortedList Nodes.
Nodes.Add(int.Parse(Node["ID"].ToString()),RootNode);
В качестве ключа используем ID ноды.
После этого добавляем все остальные ноды.
while(Node.Read())
{
TreeNode ParentNode = new TreeNode();
ParentNode.Text=Node["NAME"].ToString();
ParentNode.ID=Node["PARENTID"].ToString();
Nodes.Add(int.Parse(Node["ID"].ToString()),ParentNode);
}
В качестве ID для ноды берем PARENTID из таблицы.
В итоге получаем SortedList заполненный нодами нашего дерева.
Теперь это все надо собрать вместе.
for (int i=1;i<Nodes.Count;i++)
{
if(int.Parse(((TreeNode)Nodes.GetByIndex(i)).ID)!=0)
{
int lvl = int.Parse(((TreeNode)Nodes.GetByIndex(i)).ID);
TreeNode nNode = ((TreeNode)Nodes[lvl]);
nNode.Nodes.Add(((TreeNode)Nodes.GetByIndex(i)));
}
}
}
TreeOfStaff.Nodes.Add((TreeNode)Nodes.GetByIndex(0));
Перебираем все ноды в Nodes.
Сначала проверяем не является ли эта нода Root(иначе не имеет смысла
для Root родителем является Root).
Далее читаем ID ноды, ID ноды является номером родительской ноды в
Nodes.
int lvl = int.Parse(((TreeNode)Nodes.GetByIndex(i)).ID);
Находим родительскую ноду в Nodes.
TreeNode nNode = ((TreeNode)Nodes[lvl]);
Добавляем нашу ноду к родительской.
Так в цикле проходим по всему Nodes.
Дерево "собрано"!
Добавляем в наше дерево Root.
TreeOfStaff.Nodes.Add((TreeNode)Nodes.GetByIndex(0));
В итоге получаем заполненный TreeView.