Recursive TreeView en ASP.NET

Tengo un objeto de lista de tipos desde el que deseo usar para llenar una vista de árbol en asp.net c #.

Cada objeto tiene:

id | Name | ParentId 

así por ejemplo:

 id | Name | ParentId ------------------------- 1 | Alice | 0 2 | Bob | 1 3 | Charlie | 1 4 | David | 2 

En el ejemplo anterior, el padre sería Alicia teniendo dos hijos, Bob y Charlie. David es el hijo de Bob.

He tenido muchos problemas al intentar rellenar dinámicamente la vista de árbol recursivamente en c # ASP.NET

¿Alguien tiene una solución simple?

Por cierto: puede utilizar People.Id, People.Name y People.ParentId para acceder a los miembros, ya que es un objeto que pertenece a la lista.

Puedo publicar mi código hasta el momento (muchos bashs realizados) pero no estoy seguro de lo útil que será.

Creo que esto debería hacerte comenzar. MyObject una clase MyObject para imitar tu objeto.

 public class MyObject { public int Id; public int ParentId; public string Name; } 

Aquí hay un método para recursivley agregar nodos de vista de árbol basados ​​en la lista.

 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { List list = new List(); 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 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); } } 

Esta es una muestra con entidad de Categoría que hace referencia a sí misma. Primero debemos preparar nuestra fuente de datos:

 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 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 GethierarchicalTree(int? parentId=null) { var allCats = new BaseRepository().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 GetChildren(List 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(); } 

Luego en nuestro código tenemos:

  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 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())); } } } } } 
  //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); } }