Skip to content Skip to sidebar Skip to footer

Hierarchical Menu In View Based On Parent Child Class

I have a ViewModel: public class Page { public int Id { get; set; } public Page Parent { get; set; } public string Name { get; set; } public string Title { get; set

Solution 1:

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.

publicclassMenuItem
{
    publicint MenuID { get; set; }
    publicint ID { get; set; }
    public String Label { get; set; }
    public String Link { get; set; }
    public Boolean Show { get; set; }

    publicMenuItem(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;
    }
}

//

publicclassMenu
{
    publicint ID { get; set; }
    publicstring Name { get; set; }
    public List<MenuItem> MenuItems { get; set; }

    publicMenu(int id, string name)
    {
        this.ID = id;
        this.Name = name;
        this.MenuItems = new List<MenuItem>();
    }

}

// this is NavigationModel that wrap everything.

publicclassNavigationModel
{
    publicint currentMenuID { get; set; }   
    // used to determine the current displayed Menu to add// the "current" class to it. (to be set in the controller)publicint 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; }


    publicNavigationModel()
    {
        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.

privatestatic NavigationModel BuildNavigationMenu(User currentUser, string rootURL)
    {
        stringloginURL= rootURL + "Account/LogOn";

        // Main MenuMenuMainMenu=newMenu(1, "Home");
        MainMenu.MenuItems.Add(newMenuItem(1, 1, "Welcome", rootURL, true));
        MainMenu.MenuItems.Add(newMenuItem(1, 2, "How It Works", rootURL + "Home/HowDoesItWork", true));

        // Work MenuMenuWorkMenu=newMenu(2, "Work");
        WorkMenu.MenuItems.Add(newMenuItem(2, 1, "Profile", rootURL + "User/Profile/" + currentUser.ID , true));
        WorkMenu.MenuItems.Add(newMenuItem(2, 2, "Customers", "#", true));

        // Add Menus To Navigation ModelNavigationModelnavigationMenu=newNavigationModel();
        navigationMenu.Menus.Add(MainMenu);
        navigationMenu.Menus.Add(HireMenu);

        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"

publicstaticstringDisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
{ 
    publicstaticstringDisplayMenu(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;
    }

    privatestaticstringConvertToItem(this HtmlHelper helper,MenuItem item)
    {
        if (item.Show)
        {
            returnstring.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.

Post a Comment for "Hierarchical Menu In View Based On Parent Child Class"