Recursive TreeView in ASP.NET

I have an object of type list from which I wish to use to populate a treeview in asp.net c#.

Each object item has:

id | Name | ParentId

so for example:

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

In the above example, the parent would be Alice having two children Bob and Charlie. David is the child of Bob.

I have had many problems trying to dynamically populate the treeview recursively in c# ASP.NET

Does any one have a simple solution?

Btw: you can use People.Id, People.Name and People.ParentId to access the members since it is an object belonging to list.

I can post you my code so far (many attempts made) but not sure how useful it will be.


I think this should get you started. I created a MyObject class to mimic your object .

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

Here is a method to recursivley add tree view nodes based on the list.

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

This is a sample with Category entity that references itself. First we should prepare our data source:

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

Then in our code behind we have:

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