Question

I'm trying to build a vertical, static ASP Menu from the SiteMap file in which the child items for a node only display if they or their parent node are currently selected. For instance, say my SiteMap is:

Item1
Item2
- Child2.1
- Child2.2
Item3
- Child3.1
- Child3.2

On the home page (Item1), I want my static menu to appear as:

Item1
Item2
Item3

Were I on the Item2 or Child2.1 page, I want my static menu to appear as:

Item1
Item2
- Child2.1
- Child2.2
Item3

I'm trying to do this programmatically in the MasterPage during Menu_DataBound, but so far have failed. As the main navigation of my site already employs dynamic menus, I do not wish to employ them on this second-tier navigation.

In lieu of using the asp:Menu, I've tried building out the code in a Label:

Protected Sub LeftNavMenu_DataBound(sender As Object, e As System.EventArgs) Handles     
LeftNavMenu.DataBound
        If LeftNavMenu.Items.Count > 0 Then
            Dim item As MenuItem
        For Each item In LeftNavMenu.Items
            DisplayChildMenuText(item)
        Next
    Else
        lblNav.Text = "The Menu control does not have any items."
    End If
End Sub

Sub DisplayChildMenuText(ByVal item As MenuItem)
    If item.Selected Then
        lblNav.Text &= "<li><span class=""active""></span><a href=""" & item.NavigateUrl & """>" & item.Text & "</a></li>"
        If item.ChildItems.Count > 0 Then
            Dim childItem As MenuItem
            lblNav.Text &= "<ul>"
            For Each childItem In item.ChildItems
                lblNav.Text &= "<li><a href=""" & childItem.NavigateUrl & """>" & childItem.Text & "</a></li>"
            Next
            lblNav.Text &= "</ul>"
        End If
    Else
        lblNav.Text &= "<li><a href=""" & item.NavigateUrl & """>" & item.Text & "</a></li>"
    End If
End Sub

This displays the correct navigation if I'm on the top-tier links (Item2, Item3), but fails if I select a child page.

I sincerely apologize if this has been answered elsewhere. This seems like a fairly rudimentary request and something that should be built into ASP Menus, however I've tried for weeks to find a solution. Granted I may just be searching for the wrong keywords.

Was it helpful?

Solution

Figured it out. Sharing for the greater good. This evaluates each item in the menu during the MenuItemDataBound event, checks if the item is a child, checks if it's in an active node and, if it's not, removes it.

<script runat="server">
Protected Sub Menu1_MenuItemDataBound(sender As Object, e As System.Web.UI.WebControls.MenuEventArgs) Handles Menu1.MenuItemDataBound
    If e.Item.Parent IsNot Nothing Then
        If e.Item.Parent.Text <> SiteMap.CurrentNode.Title And e.Item.Parent.Text <> SiteMap.CurrentNode.ParentNode.Title Then
            e.Item.Parent.ChildItems.Remove(e.Item)
        End If
    End If
End Sub
</script>

Be sure your menu is set up to display two StaticDisplayLevels, e.g.:

<asp:Menu ID="Menu1" runat="server" DataSourceID="SiteMapDataSource1" IncludeStyleBlock="False"
    MaximumDynamicDisplayLevels="0" SkipLinkText="" StaticDisplayLevels="2">
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top