Populating ASP.NET Menu Control Recursively

In my fist article I will address a very common issue I think most of us have faced at least once, creating a tree-view from a flat list ( a self-joined database table for example ) maybe populating a asp.net menu control by a list of categories is a good example.

First We will create a database table named categories, bellow is a screenshot of the table schema :

we will use parentID column to create a self-joined table, if a category is a top level parent, then the ParentID will be zero, if not we will set the parent categoryID in parentID.

Bellow is the disused table filled with sample data :

Then we will create a very simple class called Category as follows :

 public class Category
        {
            public int CategoryId;
            public string CategoryName;
            public int ParentId;
            public List ChildCategory = new List();
        }

Using Linq to SQL, i have populated a generic list of Category class, I have called this method GetdatafromDb.

public List GetdatafromDb()
        {
            var FlatList = new List();
            var Mydata = new MydataDataContext();
            var dbResult = from categories in Mydata.Categories
                           select categories;
            foreach (var category in dbResult)
            {
                FlatList.Add(new Category() { CategoryId = category.CategoryID, CategoryName = category.CategoryName, ParentId = category.ParentID });
            }
            return FlatList;
        }

We create a method that will return a List of categories with all their subcategories based on data from GetdatafromDb() Method :

        private List ConvertCategoryListToTree(List flatList)
        {
            var rootNodes = new List();
            foreach (var node in flatList)
            {
                //The parent of this node in the flat list (if there is one).
                var parent = flatList.Find(i => i.CategoryId == node.ParentId);
                if (parent == null)
                {
                    //Collect the root nodes to return later...
                    rootNodes.Add(node);
                }
                else
                {
                    //Ignore orphans (should never happen, but just in case)...
                    if (!flatList.Exists(i => i.CategoryId == node.ParentId))
                        continue;

                    //add this node to the child list of its parent.
                    if (parent.ChildCategory == null)
                        parent.ChildCategory = new List();
                    parent.ChildCategory.Add(node);
                }
            }
            return rootNodes;
        }

we are almost done, we have a generic list of categories and their child categories are hanging off their parent, thats great we just need one other methods to render the asp.net menu Items and their
child items.

 private void BuildChildMenus(List Categorys, MenuItemCollection Items)
        {
            foreach (Category childCategory in Categorys)
            {
                MenuItem menuItem = new MenuItem(childCategory.CategoryName);
                menuItem.NavigateUrl = ResolveUrl("~/category.aspx?ID=") + childCategory.CategoryId;
                Items.Add(menuItem);

                if (childCategory.ChildCategory == null)
                    continue;

                BuildChildMenus(childCategory.ChildCategory, menuItem.ChildItems);
            }
        }

one last thing remaining is adding a asp,net menu control to your page, and add the following line to your Page_Load Method in code behind:

 BuildChildMenus(ConvertCategoryListToTree(GetdatafromDb()), MyMenu.Items);

in the codeine above ‘MyMenu’ is ID of my asp.net Menu Control.

I hope this article helped you save time on a common question most of us have faced.

Happy Coding,

Arash

3 thoughts on “Populating ASP.NET Menu Control Recursively

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s