ASP.NET Horizontal Menu Control
page 2 of 5
by Bryian Tan
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 66733/ 51

Getting Started

Here is the structure of my project. You are welcome to download this demo.

Figure 2

Putting Everything Together

First, add a Site Map to the website project. Open the web.sitemap file and populate it with your navigation data and structures. To underline certain character of the menu title, we can use the HTML underline tag (<u></u>). In order to parse the XML flawlessly we must replace the less than sign (<) with & lt; (no spaces). Then, include an accesskey and target attribute with a value to each siteMapNode. See below for example.

Site Map

Listing 1

  <siteMapNode>
      <siteMapNode url="Default.aspx" title="& lt;u>H& lt;/u>ome" description="Home" 
                   accesskey="H" />
      <siteMapNode url="~/Views/Menu1.aspx" title="& lt;u>M& lt;/u>enu1"  
                   description="Menu1" accesskey="M" />
        <siteMapNode url="~/Views/Menu2.aspx" title="M&lt;u>e&lt;/u>nu2" 
                     description="Menu2" accesskey="E" />
    
    <siteMapNode url="~/Views/Menu3.aspx" title="Me&lt;u>n&lt;/u>u3" 
                 description="Menu3" accesskey="N" target="_blank" />
        
    <siteMapNode url="~/Views/Menu4.aspx" title="Men&lt;u>u&lt;/u>4" 
                 description="Menu4" accesskey="U">
      <siteMapNode url="~/Views/Menu4Sub1.aspx" title="Menu4&lt;u>S&lt;/u>ub1" 
                   description="Menu4Sub1" 
                   accesskey="S" />
      <siteMapNode url="~/Views/Menu4Sub2.aspx" title="Menu4Su&lt;u>b&lt;/u>2" 
                   description="Menu4Sub2" 
                   target="_blank" accesskey="B" />
    </siteMapNode>
……
….
  </siteMapNode>
</siteMap>

 

Master Page

Add a Master Page to the website project. Drag a SiteMapDataSource control on to the page and then the menu control and wrap the menu control inside a div tag. The details description of each menu property can be found on Menu Properties. Set the staticdisplaylevels ="2" and orientation="Horizontal" to display the menu control in horizontal mode. We can use an inline style sheets or place the CSS style in an external file. In this tutorial, the CSS style is located in style.css file. See listing 2.

Listing 2

 
<asp:SiteMapDataSource id="MenuSource" runat="server" />
<div class="background">
   <asp:menu id="NavigationMenu" CssClass="NavigationMenu"  
        staticdisplaylevels="2" DynamicHorizontalOffset="1"
        staticsubmenuindent="1px" MaximumDynamicDisplayLevels="4"
        orientation="Horizontal"   
        DynamicPopOutImageUrl="~/Images/right-arrow.gif" 
        StaticPopOutImageUrl="~/Images/drop-arrow.gif"
        datasourceid="MenuSource"    
        runat="server" Height="30px">
 
        <staticmenuitemstyle ItemSpacing="10" CssClass="staticMenuItemStyle"/>
        <statichoverstyle CssClass="staticHoverStyle" />
        <StaticSelectedStyle CssClass="staticMenuItemSelectedStyle"/> 
        <DynamicMenuItemStyle CssClass="dynamicMenuItemStyle" />      
        <dynamichoverstyle CssClass="menuItemMouseOver" />
        <DynamicMenuStyle CssClass="menuItem" />
        <DynamicSelectedStyle CssClass="menuItemSelected" />
     
        <DataBindings>        
             <asp:MenuItemBinding DataMember="siteMapNode" 
                    NavigateUrlField="url" TextField="title"  
                    ToolTipField="description" />
        </DataBindings>
 
      </asp:menu>
</div>
 

Drag a SiteMapPath control on to the page. The purpose of this control is to display navigation path that shows the user the current page location. See listing 3.

Listing 3

<div id="e">
        <asp:SiteMapPath ID="SiteMapPath1" runat="server" 
                RenderCurrentNodeAsLink="true" 
                CssClass="currentNodeStyle"
            PathSeparator=" >> ">
            <PathSeparatorStyle ForeColor="#5D7B9D" CssClass="currentNodeStyle" />
            <CurrentNodeStyle ForeColor="#333333" CssClass="currentNodeStyle" />
            <NodeStyle ForeColor="#7C6F57"  CssClass="currentNodeStyle"  />
            <RootNodeStyle  ForeColor="#5D7B9D" CssClass="currentNodeStyle"  />
    </asp:SiteMapPath> 
</div>  

Master Page code behind

Include a MenuItemDataBound and SiteMapResolve event handlers on to the Page_Load event. The purpose of the former event is to insert the target attribute value and create access key for the menu item before it is rendered or displayed in a Menu control. The latter event is to modify the text displayed by the SiteMapPath control.

Listing 4

NavigationMenu.MenuItemDataBound += new               
      MenuEventHandler(NavigationMenu_MenuItemDataBound);
SiteMap.SiteMapResolve += 
      new SiteMapResolveEventHandler(SiteMap_SiteMapResolve);

Below is the implementation of the NavigationMenu_MenuItemDataBound method. The MenuItemDataBound event occurs when a menu item in a Menu control is bound to data.  That being said, it will loop through each siteMapNode and look for the accesskey and target attribute. There is a target property associated with the menu item and we can set its target window with the target attribute value.  See listing 5.

Listing 5

void NavigationMenu_MenuItemDataBound(object sender, MenuEventArgs e)
    {
        SiteMapNode node = (SiteMapNode)e.Item.DataItem;
       
        //set the target of the navigation menu item (blank, self, etc...)
        if (node["target"] != null)
        {
            e.Item.Target = node["target"];
        }
        //create access key button
        if (node["accesskey"] != null)
        {
            CreateAccessKeyButton(node["accesskey"as string, node.Url);
        }
    }

To get the access key to work, add a Panel control on to the master page and a JavaScript function to redirect the webpage to the one that is specified. See below.

Listing 6

<asp:Panel ID="AccessKeyPanel" runat="server" />
 
<script type="text/javascript">
 function navigateTo(url) {
    window.location = url;
 }
</script>

Below is the implementation of the CreateAccessKeyButton method.  Create an HtmlButton control dynamically and attach an onclick event to it. Set the style.left property to -2555px to hide the control. A complete list of access key in different browsers is available here.

Listing 7

//create access key button
    void CreateAccessKeyButton(string ak, string url)
    {
        HtmlButton inputBtn = new HtmlButton();
        inputBtn.Style.Add("width", "1px");
        inputBtn.Style.Add("height", "1px");
        inputBtn.Style.Add("position", "absolute");
        inputBtn.Style.Add("left", "-2555px");
        inputBtn.Style.Add("z-index", "-1");
        inputBtn.Attributes.Add("type", "button");
        inputBtn.Attributes.Add("value", "");
        inputBtn.Attributes.Add("accesskey", ak);
        inputBtn.Attributes.Add("onclick", "navigateTo('" + url + "');");
 
        AccessKeyPanel.Controls.Add(inputBtn);
    }

The SiteMap.SiteMapResolve event get trigger when the CurrentNode property is accessed. It will call the ReplaceNodeText method recursively and replace the HTML underline tag. See listing 8.

 

Listing 8

SiteMapNode SiteMap_SiteMapResolve(object sender, SiteMapResolveEventArgs e)
    {
        SiteMapNode currentNode = SiteMap.CurrentNode.Clone(true);
        SiteMapNode tempNode = currentNode;
        tempNode = ReplaceNodeText(tempNode);
 
        return currentNode;
    }
 
    //remove <u></u> tag recursively
    internal SiteMapNode ReplaceNodeText(SiteMapNode smn)
    {
        //current node
        if (smn != null && smn.Title.Contains("<u>"))
        {
            smn.Title = smn.Title.Replace("<u>", "").Replace("</u>""");
        }
 
        //parent node
        if (smn.ParentNode != null)
        {
            if (smn.ParentNode.Title.Contains("<u>"))
            {
                SiteMapNode gpn = smn.ParentNode;
                smn.ParentNode.Title = smn.ParentNode.Title
                    .Replace("<u>", "").Replace("</u>""");
                smn = ReplaceNodeText(gpn);
            }
        }
        return smn;
    }

Using the Code

Since the menu is in the master page, right click the website project, add new item, Web Form and check the Select Master Page checkbox.

 


View Entire Article

User Comments

Title: How do i   
Name: Sagar Joshi
Date: 2010-11-05 11:48:20 PM
Comment:
Hey.its a nice work.But i want a menu in which parent is Home.aspx then its child default.aspx & default2.aspx.Then again Parent Contact.aspx its child Address.aspx,Phone.aspx.I dont know how to arrange it in sitemap.Menu should be
Home-default,default
Contact-Address,Phone.
Home & Contact are on same hierarchy level.Plz help me on this.
Title: menu control   
Name: surinder bedi
Date: 2010-10-29 3:47:28 AM
Comment:
i'm asking about how to link menu items to other pages like by clicking "home" we should move to that particular page.
Title: how to download this demo   
Name: Bryian Tan
Date: 2010-09-14 1:14:30 AM
Comment:
Hello Nancy,

The link is located at the bottom of the article, please follow this link http://blog.ysatech.com/post/2009/12/14/ASP-NET-Horizontal-Menu-Control.aspx to download the latest source code.

Thanks,
Bryian Tan
Title: how to download this demo   
Name: Nancy
Date: 2010-09-13 11:08:49 PM
Comment:
Hi,

how do i download this Demo. I couldn't find the download link.

Thanks,
Nancy
Title: Working perfectly in Firefox not in IE8   
Name: Jagadish
Date: 2010-08-16 7:07:47 AM
Comment:
it a good project for learners using menu control
but i want to learn menus using sql data base
if u know that plz send me to my mail and my mail id is;jagadish1883@gmail.com
Title: Working perfectly in Firefox not in IE8   
Name: Bryian Tan
Date: 2010-03-29 6:52:45 PM
Comment:
Elangesh,

Please get the latest code from here:

http://blog.ysatech.com/post/2009/12/14/ASP-NET-Horizontal-Menu-Control.aspx

Thanks,
Bryian Tan
Title: Working perfectly in Firefox not in IE8   
Name: Bryian Tan
Date: 2010-03-29 6:50:27 PM
Comment:
Elangesh,

Did the demo work well on IE8?

Thanks,
Bryian Tan
Title: Working perfectly in Firefox not in IE8   
Name: Elangesh
Date: 2010-03-29 6:37:15 AM
Comment:
Hi,

I just downloaded and extracted this very good project and instantly found this works well in Firefox 3.6.2 and not working in IE8. It is a real strange. Can any one help me on this?

Many thanks,
Elangesh
Title: Help required for role based Menu   
Name: Bryian Tan
Date: 2010-03-22 7:44:06 PM
Comment:
Hello,

Try change this line in the .sitemap
&lt;siteMapNode url="" title="" description="" Text=""> TO

&lt;siteMapNode url="" role="*" title="" description="" Text="">

http://msdn.microsoft.com/en-us/library/ms178428.aspx

Thanks,
Bryian Tan
Title: Help required for role based Menu   
Name: aman kumar
Date: 2010-03-22 1:08:56 AM
Comment:
Hello,

When I am using this menu control withthe given below section in Web.config then the menu control is getting disappeared rather than trimming the Menu control according to the roles.


securityTrimmingEnabled="true

Please help on this.

Aman kumar
Title: Feedback   
Name: Manish
Date: 2010-02-21 8:35:21 AM
Comment:
Good one!
Title: New Update   
Name: Bryian Tan
Date: 2010-02-04 12:49:56 AM
Comment:
Hello,

Thanks for the feedback. I have updated the article and source code. http://blog.ysatech.com/post/2009/12/14/ASP-NET-Horizontal-Menu-Control.aspx

Please try the demo again http://download.ysatech.com/ASP-NET-Menu-Control/ and let me know how it goes.

Thanks,
Bryian Tan
Title: I agree   
Name: G W
Date: 2010-02-03 3:13:11 PM
Comment:
I agree with Kelly. I'm seeing the same thing in both browsers.
Title: Not working right in Chrome   
Name: Kelly D
Date: 2010-02-03 1:00:12 AM
Comment:
Another observation, your Chrome fix isn't working in my Chrome (not right away anyway..). When the page first loads in my Chrome (Chrome 4.0.429, Vista Home), all the menu items are stacked on top of each other until I click on any of the menu items for the first time and then they all line up properly in the horizontal menu. Plus, the Menu5A submenu flyouts are all gapped apart.
...geez, I though the days of browser incompatibilities were finally over once everybody adopted a standard. Guess not. (probably MS fault. ASP.Net not strictly complying with standards..)
Title: TreeView displaying in IE8   
Name: Kelly D
Date: 2010-02-03 12:43:18 AM
Comment:
I don't know if this is happening to everybody or not, but in my IE8, your demo is displaying the TreeView instead of the horizontal menu. Makes me think that IE8 (at least mine anyway, p.s. mine is IE8 in Vista Home..) is triggering your Browser.IsMobileDevice code for some reason.

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-20 4:49:10 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search