tags:

views:

41

answers:

1

One question I have yet to find an answer on is this. How do I keep track of active Sitemap nodes on multiple levels?

For example :

  • node 1
  • node 2 "active"
    • Child node 1
    • Child node 2 "active"
  • node 3

How do I keep track of a childnode being active as well as the parent it belongs to being marked as active.

I know there is something called IsDescendant but I always get exceptions when using it due to null values.

Is there some screencast/tutorial on doing more advanced custom navigation in mvc.net(or asp.net for that matter). Most seem to deal with simple one level navigation.

I would prefer examples in C# if possible, thank you.

+1  A: 

Ok ,,, I've suffered from the same issue and I came up with a work around, check my answer in this question :

http://stackoverflow.com/questions/3640269/hierarchical-menu-in-view-based-on-parent-child-class/3640829#3640829

I've been meaning to come up with a more generic elegant way of doing it since I've faced the problem but I've been busy ever since. I'm hoping I'll find some time in the next weeks to come up with something ,,,


Note : for simplicity in my solution in the above question in the methods DisplayMenu and ConvertToItem particularity, I've removed the parts where it should check for the currentMenuID and the currentMenuItemID fields and add the current css class to the li element (or active class in your case).

Since this is all what's your question is about, I've provided the full methods below.

public static string DisplayMenu(this HtmlHelper helper, NavigationModel navigationMenu)
    {            
        string classOfCurrentMenu;


        String result = "<ul id='main-nav'>\n";
        foreach(Menu menu in navigationMenu.Menus)
        {
            classOfCurrentMenu = "";
            if (menu.ID == navigationMenu.currentMenuID)
            {
                classOfCurrentMenu = "current";
            }

            result +=     "<li>\n";
            result +=         string.Format("<a href='#' class='{0}'> {1} </a>\n", helper.AttributeEncode(classOfCurrentMenu),helper.AttributeEncode(menu.Name));
            result +=         "<ul>\n";
            foreach(MenuItem item in menu.MenuItems)
            {
                result += NavigationHelper.ConvertToItem(helper, item, navigationMenu.currentMenuID, navigationMenu.currentMenuItemID);
            }
            result +=         "</ul>\n";
            result +=     "</li>\n";
        }
        result +=     "</ul>\n";

        return result;
    }


private static string ConvertToItem(this HtmlHelper helper,MenuItem item, int currentMenuID, int currentMenuItemID)
    {
        if (item.Show)
        {
            string classOfCurrentItem = "";
            if (item.ID == currentMenuItemID && item.MenuID == currentMenuID)
                classOfCurrentItem = "current";

            return string.Format("<li><a href='{0}' class='{1}'>{2}</a></li>\n", helper.AttributeEncode(item.Link), helper.AttributeEncode(classOfCurrentItem), helper.AttributeEncode(item.Label));
        }
        else { return ""; }   
    }

I don't consider this as a perfect solution to the problem, I hate writing HTML in C# code, I will try my best to come up with a more generic (multi level) cleaner solution for the problem, and of course make use of the TagBuilder class in the framework.

Manaf Abu.Rous
Wow that was helpful. I have searched and searched and didn't find anything really useful on this subject. I will try this.
Marcus J. Maunula