May 4, 2014 by Nitesh

How To Create Multi Level Menu Dynamically Using C# in ASP.Net

Friends,

This is Part 4 of the series “Creating Menus”. We have already seen how to create a single level menu dynamically in ASP.Net here. This post will explain how to create a multi-level menu dynamically using C# in Asp.Net. You can also read the other 2 posts in this series with the links mentioned below –

To begin with, we will make some changes to our Categories table in our database to hold Parent and child relationships between the menus.  We added a ParentCategoryID in our table that will store the Parent CategoryID of the menu present in record. For parent categories, vlue in this column equals Zero. Now, the table structure looks something like below-

dynamic-multi-level-menu-1

After the structure is defined, its time to fill in with some dummy data. Lets assume we have the below data.

dynamic-multi-level-menu-2

Our DB is defined. Time to write some code! We make changes to our existing Repeater Control adding a Literal control that will hold all sub menus of parent menu. An important thing to note in this markup is we have handled the “ItemDataBound” event of the Repeater control.

<asp:repeater ID="rptCategories" runat="server" OnItemDataBound="rptCategories_ItemDataBound">
                    <headertemplate>
                        <div class="menu"><ul>
                    </ul></div></headertemplate>
                    <itemtemplate>
                        <li>
                            <a href='#'>< %#Eval("Name") %></a>
                            <asp:literal ID="ltrlSubMenu" runat="server"></asp:literal>
                        </li>
                    </itemtemplate>
                <footertemplate>
                    
                </footertemplate>
                </asp:repeater>

In the code file (.master.cs/.aspx.cs/.acsx.cs), we will make a call to our database to get all the categories and bind the data to the repeater control.  For doing this, we will write the below code.

        DataTable allCategories=new DataTable();
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                LoadCategories();
            }
        }
        private void LoadCategories()
        {
            allCategories = GetAllCategories();
            rptCategories.DataSource = GetCategories();
            rptCategories.DataBind();
        }
        private void GetCategories()
        {
        SqlConnection connection = new SqlConnection("Data Source=NITESH;Initial Catalog=TestDB;Integrated Security=SSPI;" providerName="System.Data.SqlClient");
        SqlCommand selectCommand = new SqlCommand("SELECT ID,CategoryName FROM Categories WHERE ParentCategoryID=0", connection);
        DataTable dt = new DataTable();
        try
        {
            connection.Open();
            SqlDataReader reader = selectCommand.ExecuteReader();
            if (reader.HasRows)
            {
                dt.Load(reader);
            }
            reader.Close();
        }
        catch (SqlException)
        {
            throw;
        }
        finally
        {
            connection.Close();
        }
        }
        private void GetAllCategories()
        {
        SqlConnection connection = new SqlConnection("Data Source=NITESH;Initial Catalog=TestDB;Integrated Security=SSPI;" providerName="System.Data.SqlClient");
        SqlCommand selectCommand = new SqlCommand("SELECT ID,CategoryName FROM Categories", connection);
        DataTable dt = new DataTable();
        try
        {
            connection.Open();
            SqlDataReader reader = selectCommand.ExecuteReader();
            if (reader.HasRows)
            {
                dt.Load(reader);
            }
            reader.Close();
        }
        catch (SqlException)
        {
            throw;
        }
        finally
        {
            connection.Close();
        }
        }
        protected void Categories_ItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType==ListItemType.AlternatingItem)
            {
                if (allCategories != null)
                {
                    DataRowView drv = e.Item.DataItem as DataRowView;
                    string ID = drv["ID"].ToString();
                    DataRow[] rows = allCategories.Select("ParentCategoryID=" + ID, "Name");
                    if (rows.Length > 0)
                    {
                        StringBuilder sb = new StringBuilder();
                        sb.Append("<ul>");
                        foreach (var item in rows)
                        {
                            sb.Append("<li><a href='#'>" + item["CategoryName"] + "</a></li>");
                        }
                        sb.Append("</ul>");
                        (e.Item.FindControl("ltrlSubMenu") as Literal).Text = sb.ToString();
                    }
                }
            }
        }

If you see the code above, most of the code is similar to our previous post. So, I will explain the remaining part in this post. 1st of all we are binding only parent categories to the Repeater control in GetCategories(). Secondly, we get all categories in a separate DataTable (lets call it Main DT for this post in future references) which we will use in the rptCategories_ItemDataBound() event handler. Inside the event handler, we check if the current item is a valid Item(while binding Repeater control fires this event for binding header and footer rows as well). If yes, we get the ID of the current record and filter our main DT where ParentCategoryID = ID of the current record so that we have all child categories for the current menu. Once filtered, we create a dynamic HTML string using <ul> and <li> tags and finally assign this text to the Literal control defined in our .aspx page.

At this point, you’re done with your main coding part and as always you need to apply CSS to the menus. Add the below CSS to your .css file and execute the application.

.menu{
    width: 500px;
    margin: 0px auto;
    font-family: Arial, Helvetica, sans-serif;
    font-weight: bold;
    font-size: 14px;
}
.menu ul li a:link, div ul li a:visited {
    display: block;
    background-color: #f1f1f1;color:#000;
    text-align: center;
    text-decoration: none;
    padding: 4px;
    border-bottom: 1px solid #fff;
    width: 150px;        
}
.menu ul li a:hover{
    background-color: #ccc;
}
.menu ul li ul li a:link, li ul li a:visited {
    display: block;
    background-color: #f1f1f1;
    color: #000;
    text-align: center;
    text-decoration: none;
    padding: 4px;
    border-bottom: 1px solid #fff;
    width: 150px;
}
.menu ul li ul li a:hover {
    background-color: #ccc;
}
.menu ul {
    list-style-type: none;
    margin: 0px;
    padding: 0px;   
}
.menu ul li {
    float: left;
    margin-left: 5px;
}
.menu ul li ul li {
    float: none;
    margin-left: 0px;
}
.menu ul li ul {
    display: none;  
}
.menu li:hover ul{
    display: block; 
}

You will see the output something like below.

dynamic-multi-level-menu-3

Hope you like this post! Keep learning and sharing folks!

#.Net#ASP.Net#C##CSS#HTML#Menu
  • chinmay

    Hi thanks your code was extremely helpful.
    Can you please suggest changes needed for applying the same for 2nd level menu in it.
    I am not able to add submenu to it.
    Thanks

  • Udani Wijesinghe

    when i execute this code.i got some errors like below.can you help to solve this?

    • What errors are you getting?

    • At which line are you getting this error?

    • Udani Wijesinghe

      I’m sorry dear.When i clean and rebuild the application,it’s working.thanks for your quick response.thanks again and again.great article.sorry for my mistake.

  • alvz

    thank you!!!!!!

  • thanhducn

    I am not able to add submenu to 2nd level menu. Please help me.
    Thank you.

Support us!

If you like this site please help and make click on any of these buttons!

Powered by WordPress Popup