Click here to Skip to main content
15,880,891 members
Articles / Web Development / ASP.NET

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

Rate me:
Please Sign up or sign in to vote.
4.83/5 (10 votes)
24 Jul 2014CPOL2 min read 135.5K   14   34
This post will explain how to create a multi-level menu dynamically using C# in ASP.NET.

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, value in this column equals Zero. Now, the table structure looks something like below:

dynamic-multi-level-menu-1

After the structure is defined, it's time to fill in with some dummy data. Let's 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.NET
<asp:repeater ID="rptCategories" runat="server" 
OnItemDataBound="rptCategories_ItemDataBound">
                    <headertemplate>
                        <div class="menu"><ul>
                    </headertemplate>
                    <itemtemplate>
                        <li>
                            <a href='#'>< 
                            %#Eval("Name") %></a>
                            <asp:literal ID="ltrlSubMenu" 
                            runat="server"></asp:literal>
                        </li>
                    </itemtemplate>
                <footertemplate>
                       </ul></div>
                </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.

C#
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 DataTable 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();
}
return dt;
}
private DataTable 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();
}
return dt;
}
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. First of all, we are binding only parent categories to the Repeater control in GetCategories(). Secondly, we get all categories in a separate DataTable (let's 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.

CSS
.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!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder Rebin Infotech
India India
A passionate developer with over 10 years of experience and building my software company code by code. Experience withMS Technologies like .Net | MVC | Xamarin | Sharepoint | MS Project Server and PhP along with open source CMS Systems like Wordpress/DotNetNuke etc.

Love to debug problems and solve them. I love writing articles on my website in my spare time. Please visit my Website for more details and subscribe to get technology related tips/tricks. #SOreadytohelp

Comments and Discussions

 
QuestionHow To Create Multi Level Menu Dynamically Using C# in ASP.NET Pin
Software Developer Sep202131-Aug-21 22:04
Software Developer Sep202131-Aug-21 22:04 
Question3 level tree archtecture by this code Pin
Member 1131353527-Sep-16 1:47
Member 1131353527-Sep-16 1:47 
QuestionHere is another method without the need for sql Pin
Louis Lakser21-Jul-16 5:51
Louis Lakser21-Jul-16 5:51 
AnswerRe: Here is another method without the need for sql Pin
Nitesh Kejriwal21-Jul-16 7:01
professionalNitesh Kejriwal21-Jul-16 7:01 
Answershort method to create menu dynamically Pin
Member 1164850819-Jul-15 21:54
Member 1164850819-Jul-15 21:54 
public partial class admin : System.Web.UI.Page
{
SqlCommand cmd;
SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ToString());
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
bindmenu();
}
}
private void bindmenu()
{
con.Open();
DataSet ds = new DataSet();
DataTable dt = new DataTable();
string sql = "Select *from [Categories]";
SqlDataAdapter da = new SqlDataAdapter(sql, con);
da.Fill(ds);
dt = ds.Tables[0];
DataRow[] drowparent = dt.Select("ParentCategoryID=" + 0);
foreach (DataRow dr in drowparent)
{

Menu1.Items.Add(new MenuItem(dr["CategoryName"].ToString(), dr["ID"].ToString(), dr["ParentCategoryID"].ToString()));

}
foreach (DataRow dr in dt.Select("ParentCategoryID>" + 0))
{

{
MenuItem men1 = new MenuItem(dr["CategoryName"].ToString(), dr["ID"].ToString(), dr["ParentCategoryID"].ToString());
Menu1.FindItem(dr["ParentCategoryID"].ToString()).ChildItems.Add(men1);
}
}



}

}

modified 20-Jul-15 6:38am.

QuestionWant to create a 2nd level menu.. Pin
Member 1115919411-Nov-14 2:55
Member 1115919411-Nov-14 2:55 
AnswerRe: Want to create a 2nd level menu.. Pin
Nitesh Kejriwal11-Nov-14 16:31
professionalNitesh Kejriwal11-Nov-14 16:31 
GeneralRe: Want to create a 2nd level menu.. Pin
Member 1115919411-Nov-14 17:28
Member 1115919411-Nov-14 17:28 
GeneralRe: Want to create a 2nd level menu.. Pin
Nitesh Kejriwal11-Nov-14 19:05
professionalNitesh Kejriwal11-Nov-14 19:05 
GeneralRe: Want to create a 2nd level menu.. Pin
ahmed2071-Feb-15 20:33
ahmed2071-Feb-15 20:33 
GeneralRe: Want to create a 2nd level menu.. Pin
Nitesh Kejriwal1-Feb-15 20:41
professionalNitesh Kejriwal1-Feb-15 20:41 
GeneralGood stuff Pin
Gaurav Aroraa27-Oct-14 10:24
professionalGaurav Aroraa27-Oct-14 10:24 
GeneralMy vote of 4 Pin
MB Seifollahi26-Jul-14 1:32
professionalMB Seifollahi26-Jul-14 1:32 
GeneralRe: My vote of 4 Pin
Nitesh Kejriwal26-Jul-14 2:42
professionalNitesh Kejriwal26-Jul-14 2:42 
AnswerRe: My vote of 4 Pin
MB Seifollahi26-Jul-14 4:56
professionalMB Seifollahi26-Jul-14 4:56 
GeneralRe: My vote of 4 Pin
Nitesh Kejriwal27-Jul-14 19:33
professionalNitesh Kejriwal27-Jul-14 19:33 
AnswerRe: My vote of 4 Pin
MB Seifollahi28-Jul-14 22:22
professionalMB Seifollahi28-Jul-14 22:22 
QuestionNeed help debugging Pin
Dannoman123425-Jul-14 5:54
Dannoman123425-Jul-14 5:54 
AnswerRe: Need help debugging Pin
Nitesh Kejriwal25-Jul-14 7:56
professionalNitesh Kejriwal25-Jul-14 7:56 
QuestionArticle needs a correction Pin
Dannoman123425-Jul-14 5:22
Dannoman123425-Jul-14 5:22 
AnswerRe: Article needs a correction Pin
Nitesh Kejriwal25-Jul-14 7:55
professionalNitesh Kejriwal25-Jul-14 7:55 
GeneralRe: Article needs a correction Pin
Dannoman123425-Jul-14 7:57
Dannoman123425-Jul-14 7:57 
GeneralRe: Article needs a correction Pin
Nitesh Kejriwal25-Jul-14 8:19
professionalNitesh Kejriwal25-Jul-14 8:19 
QuestionCSS is not applying to RepeaterControl Pin
Dannoman123424-Jul-14 6:27
Dannoman123424-Jul-14 6:27 
AnswerRe: CSS is not applying to RepeaterControl Pin
Nitesh Kejriwal24-Jul-14 7:26
professionalNitesh Kejriwal24-Jul-14 7:26 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.