Loop Through Multi-Level Dynamic Menus in Asp.Net MVC

10,033

You could use a partialview and then do a recursive loop. In order to do that you'd first need to change your Model a bit:

ViewModel

// The ViewModel is now a hirearchical model, where each item has a list of children.
public class MenuViewModel
{
    int MenuId {get; set;}
    string Name {get; set;}
    //other properties
    ** snip ** 
    List<MenuViewModel> Children {get; set;}
}

Controller

Transform model into the hierarchical ViewModel:

public ActionResult Menus(){
    List<Menu> menusource; // get your menus here
    ViewBag.Menus = CreateVM(0, menusource);  // transform it into the ViewModel
    return View();
}

public IEnumerable<MenuViewModel> CreateVM(int parentid, List<Menu> source)
{
    return from men in source
           where men.ParentId = parentid
           select new MenuViewModel(){
                      MenuId = men.MenuId, 
                      Name = men.Name
                      // other properties
                      Children = CreateVM(men.MenuId, source)
                  };
}

View

@{ 
    var menusList = ViewBag.Menus as IEnumerable<MenuViewModel>; 
    Html.RenderPartial("MenuPartial", menuslist);
}

MenuPartial

@model IEnumerable<MenuViewModel>

@foreach (var menuitem in model)
{
    <ul>
        <li>
            <h1>@menuitem.Name</h1>
            @{
                Html.RenderPartial("MenuPartial", menuitem.Children);
            }
        </li>
    </ul>
}

The only thing you will be missing here with regards to your original code is that you don't have different Hx-tags, but you could find a way around that by creating another viewmodel and passing it the level you are currently at.

Note: I typed up all this code in the SO-editor, so there may be some small syntax errors.

Share:
10,033
Idrees Khan
Author by

Idrees Khan

Well, in short. I love working with new technologies in Web, Mobile and Desktop. Techs such Angular, React, .Net, Xamarin, Ionic, Angular, Node are the one i am mostly targeting. I love building new things (of course not buildings) and i am very passionate by playing with many .js frameworks.

Updated on August 01, 2022

Comments

  • Idrees Khan
    Idrees Khan almost 2 years

    i am trying to loop through multilevel dynamic menus. I have been succeeded to do this manually i.e everytime if want to display the child Menus of it's parent, I have to loop manually. I would like to know the best way or an alternative of looping multi-level through these dynamic menus Here is what i have done so far;

    @{ var menusList = ViewBag.Menus as IEnumerable<ParentMenuViewModel>; }
    @foreach (var parentMenu in menusList.Where(p => p.ParentId == 0))
    {
        <ul>
            <li>
                <h1>@parentMenu.Name</h1>
                @if (menusList.Count(p => p.ParentId == parentMenu.MenuId) > 0)
                {
                    <ul>
                        @foreach (var childMenu in menusList.Where(p => p.ParentId == parentMenu.MenuId))
                        {
                            <h2>@childMenu.Name</h2>
                            if (menusList.Count(p => p.ParentId == childMenu.MenuId) > 0)
                            {
                                foreach (var subChild in menusList.Where(p => p.ParentId == childMenu.MenuId))
                                {
                                    <h3>@subChild.Name</h3>
                                }
                            }
                        }
                    </ul>
                }
            </li>
        </ul>
    
    }
    

    UPDATE: The output looks like this;

    HOME
     SUB MENU1
      SUB SUB MENU1
      SUB SUB MENU2
    

    However, i have in my database something like this;

    HOME
     SUB MENU1
      SUB SUB MENU1
      SUB SUB MENU2
        Sub SUB SUB MENU1
        Sub SUB SUB MENU2
    

    Here is my model;
    enter image description here