Hierarchical menu in view based on parent child class

there are many ways to display dynamicly generated menus and i will post my way of doing it, I have two classes Menu & MenuItem (a Menu is just a wrapper for a list of MenuItems which are the actual >”real” links) and then i have a NavigationViewModel to wrap everything.

public class MenuItem
    public int MenuID { get; set; }
    public int ID { get; set; }
    public String Label { get; set; }
    public String Link { get; set; }
    public Boolean Show { get; set; }

    public MenuItem(int menuId, int id, string label, string link, Boolean show)
        this.MenuID = menuId;
        this.ID = id;
        this.Label = label;
        this.Link = link;
        this.Show = show;


public class Menu
    public int ID { get; set; }
    public string Name { get; set; }
    public List<MenuItem> MenuItems { get; set; }

    public Menu(int id, string name)
        this.ID = id;
        this.Name = name;
        this.MenuItems = new List<MenuItem>();


// this is NavigationModel that wrap everything.

public class NavigationModel
    public int currentMenuID { get; set; }   
    // used to determine the current displayed Menu to add
    // the "current" class to it. (to be set in the controller)

    public int currentMenuItemID { get; set; } 
    // used to determine the current displayed MenuItem to add
    // the "current" class to it. (to be set in the controller)

    public List<Menu> Menus { get; set; }

    public NavigationModel()
        this.Menus = new List<Menu>();
        // Set Default Menu ( Menu 1 )
        this.currentMenuID = 1;
        // Set Default Menau Item ( None )
        this.currentMenuItemID = 0;

// This is an example of a method that builds a NavigationModel.

private static NavigationModel BuildNavigationMenu(User currentUser, string rootURL)
        string loginURL = rootURL + "Account/LogOn";

        // Main Menu
        Menu MainMenu = new Menu(1, "Home");
        MainMenu.MenuItems.Add(new MenuItem(1, 1, "Welcome", rootURL, true));
        MainMenu.MenuItems.Add(new MenuItem(1, 2, "How It Works", rootURL + "Home/HowDoesItWork", true));

        // Work Menu
        Menu WorkMenu = new Menu(2, "Work");
        WorkMenu.MenuItems.Add(new MenuItem(2, 1, "Profile", rootURL + "User/Profile/" + currentUser.ID , true));
        WorkMenu.MenuItems.Add(new MenuItem(2, 2, "Customers", "#", true));

        // Add Menus To Navigation Model
        NavigationModel navigationMenu = new NavigationModel();

        return navigationMenu;

// I have a NavigationHelper that takes care of outputting the HTML with the following two methods.

Note: (this is a simplified version as in my implementation i use the id of the Menu & the MenuItem to locate the current menu that is being displayed and add the “current” CSS class to it”

public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
    public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
        String result = "<ul id='main-nav'>\n";
        foreach(Menu menu in navigationMenu.Menus)
            result +=     "<li>\n";
            result +=         string.Format("<a href='#'> {0} </a>\n",helper.AttributeEncode(menu.Name));
            result +=         "<ul>\n";
            foreach(MenuItem item in menu.MenuItems)
                result += NavigationHelper.ConvertToItem(helper, item);
            result +=         "</ul>\n";
            result +=     "</li>\n";
        result +=     "</ul>\n";

        return result;

    private static string ConvertToItem(this HtmlHelper helper,MenuItem item)
        if (item.Show)
            return string.Format("<li><a href='{0}'>{1}</a></li>\n", helper.AttributeEncode(item.Link), helper.AttributeEncode(item.Label));
        else { return ""; }   

finally i have a following call in my Master to display the menu.

<!-- Navigation -->
<%= Html.DisplayMenu(Model.NavigationMenu) %>

Note: I have a strongly typed MasterPage with the type (BaseViewModel) that contains the property NavigationMenu of type NavigationModel

Connecting everything together.

In my example i have to supply my Views with a ViewModel (that inherits my BaseViewModel) at each action method to and then build the Menu (using a Builder Method that does most of the work so i don’t have to re type it in every action method). If you don’t use a BaseViewModel then you will need to find another way to build the Navigation Model and then pass the Navigation Model to your MasterPage.

For me i find having a strongly typed MasterPage to make things easier and cleaner. King wilder have a nice way of implementing them in his GolfTracker Series.


About Nguyễn Viết Hiền

Passionate, Loyal
This entry was posted in Uncategorized. Bookmark the permalink.

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 )

Google+ photo

You are commenting using your Google+ 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 )


Connecting to %s