ASP.Net provides Menu Control to display top navigation. But
the problem with that Menu is its complexity while rendering on the Page. It
renders the Menu as html table and each menu item is an individual table.
I have developed a user control to render the top menu using
UL and LI tags. This control uses a Repeater to render the menu items. For now I
have developed it to render Top level menu items.
CustomMenu.Ascx
<%@ Control
Language="C#"
AutoEventWireup="true"
CodeFile="CustomMenu.ascx.cs"
Inherits="UserControls_CustomMenu"
%>
<ul id="menu">
<asp:Repeater ID="rptMainNav"
runat="server"
OnItemDataBound="rptMainNav_OnItemDataBound"
>
<ItemTemplate>
<li id="menuItem"
runat="server" >
<a href="#" id="menuLink"
runat="server"
></a>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
<asp:SiteMapDataSource ID="SiteMapDataSource"
runat="server"
ShowStartingNode="false"
/>
CustomMenu.Ascx.cs
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
public partial class UserControls_CustomMenu
: System.Web.UI.UserControl
{
protected void
Page_Load(object sender, EventArgs e)
{
rptMainNav.DataSourceID = "SiteMapDataSource";
rptMainNav.DataBind();
}
protected void
rptMainNav_OnItemDataBound(object sender, RepeaterItemEventArgs e)
{
SiteMapNode siteMapNode = e.Item.DataItem as SiteMapNode;
if (siteMapNode != null
&& (e.Item.ItemType == ListItemType.Item
|| e.Item.ItemType == ListItemType.AlternatingItem))
{
HtmlAnchor menuLink = e.Item.FindControl("menuLink") as
HtmlAnchor;
HtmlControl menuItem = e.Item.FindControl("menuItem") as
HtmlControl;
if (menuLink != null)
{
menuLink.HRef = siteMapNode.Url;
menuLink.InnerHtml = siteMapNode.Title;
if (BelongsToThisNode(SiteMap.CurrentNode, siteMapNode))
{
menuItem.Attributes.Add("class",
"selected");
}
}
}
}
private bool
BelongsToThisNode(SiteMapNode siteMapNode,SiteMapNode parentNode)
{
if (siteMapNode.Url == parentNode.Url)
return true;
if (siteMapNode.ParentNode == null || string.IsNullOrEmpty(siteMapNode.ParentNode.Url))
return false;
if (siteMapNode.ParentNode != null && siteMapNode.ParentNode.Url == parentNode.Url)
return true;
return BelongsToThisNode(siteMapNode.ParentNode,
parentNode);
}
}
Web.sitemap
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="" title="" description="">
<siteMapNode url="~/Default.aspx" title="Home" description="" />
<siteMapNode url="~/AboutUs.aspx" title="About Us" description="" >
<siteMapNode url="~/Leadership.aspx" title="Leadership" description="" ></siteMapNode>
</siteMapNode>
<siteMapNode url="~/Services.aspx" title="Services" description="" />
<siteMapNode url="~/ContactUs.aspx" title="Contact Us" description="" >
<siteMapNode url="~/Career.aspx" title="Leadership" description="" ></siteMapNode>
</siteMapNode>
</siteMapNode>
</siteMap>
Register this control on Master page and use it instead of
the Menu Control. It is easy to style
this control using css. The below lines of
code
if (BelongsToThisNode(SiteMap.CurrentNode,
siteMapNode))
{
menuItem.Attributes.Add("class",
"selected");
}
Will add a css class to the selected Menu Item to display it
in different style.