Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Populate TreeView from DataTable

I have created an account table in my database, with these columns:

ID
Name
ParentID

This is an example of how records have been stored:

ID   Name    ParentID
1    BANK A  0
2    0001    1
3    0002    1
4    BANK B  0
5    0001    4
6    0002    4

But the company name does not come from database, it comes from code. So how can I expand the TreeView like this?

├─ BANK A
│  ├─ 0001
│  └─ 0002
└─ BANK B
   ├─ 0001
   └─ 0002

How can I do this in C#? I also tried from HERE but I still don't understand it.

like image 502
Azri Zakaria Avatar asked Dec 22 '12 14:12

Azri Zakaria


2 Answers

i have found a piece of code that worked great for me after spending 2h to make complicated algorithlms :

 //In Page load
 //select where id is null to retrieve the parent nodes 
 //in a datatable (called table here)
 foreach (DataRow row in table.Rows)
 {
   TreeNode node = new TreeNode();
   node.Text = row["title"].ToString();
   node.Value = row["id"].ToString();
   //you can affect the node.NavigateUrl

   node.PopulateOnDemand = true;
   TreeView1.Nodes.Add(node);
 }

then create the TreeNodePopulate event :

 protected void TreeView1_TreeNodePopulate(Object sender, TreeNodeEventArgs e)
 {
     string id= e.Node.Value;
     //do your "select from yourTable where parentId =" + id;

     foreach (DataRow row in table.Rows)
     {
         TreeNode node = new TreeNode(row["title"], row["id"])
         node.PopulateOnDemand = true;    
         e.Node.ChildNodes.Add(node);
     }

 }

it worked like hell for me, i hope it will help !

like image 131
Sebastien H. Avatar answered Sep 22 '22 02:09

Sebastien H.


To populate a TreeView from a DataTable or any IEnumerable<T>, you should be able to answer the following questions:

  1. What are data source items
  2. How to detect if an item in data source is a root item in tree
  3. How to find child items of an item in data source
  4. How to create tree item from data source item.

By passing answer of above questions as lambda expressions to the following method, it uses a recursive algorithm to create a list of TreeNode which you can add to TreeView. Each TreeNode contains the descendant TreeNode items:

private IEnumerable<TreeNode> GetTreeNodes<T>(
    IEnumerable<T> source,
    Func<T, Boolean> isRoot,
    Func<T, IEnumerable<T>, IEnumerable<T>> getChilds,
    Func<T, TreeNode> getItem)
{
    IEnumerable<T> roots = source.Where(x => isRoot(x));
    foreach (T root in roots)
        yield return ConvertEntityToTreeNode(root, source, getChilds, getItem); ;
}

private TreeNode ConvertEntityToTreeNode<T>(
    T entity,
    IEnumerable<T> source,
    Func<T, IEnumerable<T>, IEnumerable<T>> getChilds,
    Func<T, TreeNode> getItem)
{
    TreeNode node = getItem(entity);
    var childs = getChilds(entity, source);
    foreach (T child in childs)
        node.Nodes.Add(ConvertEntityToTreeNode(child, source, getChilds, getItem));
    return node;
}

Example

I assume you have loaded data into the following structure:

var dt = new DataTable();
dt.Columns.Add("Id", typeof(int));
dt.Columns.Add("Name", typeof(string));
dt.Columns.Add("ParentId", typeof(int));

dt.Rows.Add(1, "Menu 1", DBNull.Value);
dt.Rows.Add(11, "Menu 1-1", 1);
dt.Rows.Add(111, "Menu 1-1-1", 11);
dt.Rows.Add(112, "Menu 1-1-2", 11);
dt.Rows.Add(12, "Menu 1-2", 1);
dt.Rows.Add(121, "Menu 1-2-1", 12);
dt.Rows.Add(122, "Menu 1-2-2", 12);
dt.Rows.Add(123, "Menu 1-2-3", 12);
dt.Rows.Add(124, "Menu 1-2-4", 12);
dt.Rows.Add(2, "Menu 2", DBNull.Value);
dt.Rows.Add(21, "Menu 2-1", 2);
dt.Rows.Add(211, "Menu 2-1-1", 21);

Then to convert it nodes of a TreeView, you can use the following code:

var source = dt.AsEnumerable();
var nodes = GetTreeNodes(
        source,
        (r) => r.Field<int?>("ParentId") == null,
        (r, s) => s.Where(x => r["Id"].Equals(x["ParentId"])),
        (r) => new TreeNode { Text = r.Field<string>("Name") }
);
treeView1.Nodes.AddRange(nodes.ToArray());

As a result, you will have the following tree structure:

├─ Menu 1
│  ├─ Menu 1-1
│  │  ├─ Menu 1-1-1
│  │  └─ Menu 1-1-2
│  └─ Menu 1-2
│     ├─ Menu 1-2-1
│     ├─ Menu 1-2-2
│     ├─ Menu 1-2-3
│     └─ Menu 1-2-4
└─ Menu 2
   └─ Menu 2-1
      └─ Menu 2-1-1
like image 39
Reza Aghaei Avatar answered Sep 18 '22 02:09

Reza Aghaei