Рекурсивное TreeView в ASP.NET
У меня есть объект списка типов, из которого я хочу использовать, чтобы заполнить дерево в asp.net С#.
Каждый объект объекта имеет:
id | Name | ParentId
так, например:
id | Name | ParentId
-------------------------
1 | Alice | 0
2 | Bob | 1
3 | Charlie | 1
4 | David | 2
В приведенном выше примере родителем будет Алиса с двумя детьми Боб и Чарли. Дэвид - ребенок Боба.
У меня было много проблем, пытающихся динамически заполнить treeview рекурсивно в С# ASP.NET
Есть ли у кого-нибудь простое решение?
Btw: вы можете использовать People.Id, People.Name и People.ParentId для доступа к элементам, поскольку это объект, принадлежащий списку.
Я могу опубликовать ваш код до сих пор (сделано много попыток), но не уверен, насколько он будет полезен.
Ответы
Ответ 1
Я думаю, это должно начаться. Я создал класс MyObject
для имитации вашего объекта.
public class MyObject
{
public int Id;
public int ParentId;
public string Name;
}
Ниже приведен метод рекурсивного добавления узлов дерева представлений на основе списка.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<MyObject> list = new List<MyObject>();
list.Add(new MyObject(){Id=1, Name="Alice", ParentId=0});
list.Add(new MyObject(){Id=2, Name="Bob", ParentId=1});
list.Add(new MyObject(){Id=3, Name="Charlie", ParentId=1});
list.Add(new MyObject(){Id=4, Name="David", ParentId=2});
BindTree(list, null);
}
}
private void BindTree(IEnumerable<MyObject> list, TreeNode parentNode)
{
var nodes = list.Where(x => parentNode == null ? x.ParentId == 0 : x.ParentId == int.Parse(parentNode.Value));
foreach (var node in nodes)
{
TreeNode newNode = new TreeNode(node.Name, node.Id.ToString());
if (parentNode == null)
{
treeView1.Nodes.Add(newNode);
}
else
{
parentNode.ChildNodes.Add(newNode);
}
BindTree(list, newNode);
}
}
Ответ 2
Это образец с субъектом категории, который ссылается на себя. Сначала мы должны подготовить наш источник данных:
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Category Parent { get; set; }
public virtual ICollection<Category> Children { get; set; }
public byte[] Image { get; set; }
}
public class Product
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public Category ProductCategory { get; set; }
public int ProductCategoryId { get; set; }
public byte[] Image { get; set; }
}
public List<Category> GethierarchicalTree(int? parentId=null)
{
var allCats = new BaseRepository<Category>().GetAll();
return allCats.Where(c => c.ParentId == parentId)
.Select(c => new Category()
{
Id = c.Id,
Name = c.Name,
ParentId = c.ParentId,
Children = GetChildren(allCats.ToList(), c.Id)
})
.ToList();
}
public List<Category> GetChildren(List<Category> cats, int parentId)
{
return cats.Where(c => c.ParentId == parentId)
.Select(c => new Category
{
Id = c.Id,
Name = c.Name,
ParentId = c.ParentId,
Children = GetChildren(cats, c.Id)
})
.ToList();
}
Тогда в нашем коде мы имеем:
protected void Page_Load(object sender, EventArgs e)
{
var hierarchicalData = new CategoryRepository().GethierarchicalTree();
tv1.Nodes.Clear();
var root = new TreeNode("0","Root");
tv1.Nodes.Add(root);
BindTreeRecursive(hierarchicalData, root);
}
private void BindTreeRecursive(List<Category> hierarchicalData, TreeNode node)
{
foreach (Category category in hierarchicalData)
{
if (category.Children.Any())
{
var n = new TreeNode(category.Name, category.Id.ToString());
node.ChildNodes.Add(n);
BindTreeRecursive(category.Children.ToList(), n);
}
else
{
var n = new TreeNode(category.Name, category.Id.ToString());
node.ChildNodes.Add(n);
if (new ProductRepository().Get(a => a.ProductCategoryId == category.Id).Any())
{
var catRelatedProducts = new ProductRepository().Get(a => a.ProductCategoryId == category.Id).ToList();
foreach (Product product in catRelatedProducts)
{
n.ChildNodes.Add(new TreeNode(product.Name,product.Id.ToString()));
}
}
}
}
}
Ответ 3
//In load for example
if (!IsPostBack)
{
DataSet ds = new DataSet();
ds = getRoles(); //function that gets data collection from db.
tvRoles.Nodes.Clear();
BindTree(ds, null);
tvRoles.DataBind();
}
private void BindTree(DataSet ds, TreeNode parentNode)
{
DataRow[] ChildRows;
if (parentNode == null)
{
string strExpr = "ParentId=0";
ChildRows = ds.Tables[0].Select(strExpr);
}
else
{
string strExpr = "ParentId=" + parentNode.Value.ToString();
ChildRows = ds.Tables[0].Select(strExpr);
}
foreach (DataRow dr in ChildRows)
{
TreeNode newNode = new TreeNode(dr["Name"].ToString(), dr["Id"].ToString());
if (parentNode == null)
{
tvRoles.Nodes.Add(newNode);
}
else
{
parentNode.ChildNodes.Add(newNode);
}
BindTree(ds, newNode);
}
}