Рекурсивное 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);
        }
    }