<

Control Visible Menus with web.sitemap

Published on
19,655 Points
10,055 Views
1 Endorsement
Last Modified:
Awarded
A quick way to get a menu to work on our website, is using the Menu control and assign it to a web.sitemap using SiteMapDataSource.

Example of web.sitemap file:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode  url="~/" title="Home"  description="Home">
         <siteMapNode url="" description="Menu 1" title="Menu 1">
             <siteMapNode url="" description="SubMenu 1" title="Sub Menu 1"/>
         </siteMapNode>
         <siteMapNode url="" description="Menu 2" title="Menu 2"/>
         <siteMapNode url="" description="Menu 3" title="Menu 3"/>
     </siteMapNode>
</siteMap>

Open in new window

Sample code to add to the page menu:
<asp:Menu ID="NavigationMenu" runat="server" CssClass="menu"
      EnableViewState="False" IncludeStyleBlock="False" Orientation="Horizontal"
      DataSourceID="SiteMapDataSource1">
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server"  ShowStartingNode="false" />

Open in new window

Running the application, we will have something like the next picture:
 menu1rc.png
To show or hide the menu depending on the type of access each user, we may define the Roles in each SiteMapNode.

Another way to control the menus visible, is to add an attribute in each SiteMapNode and depending on its value, or will not display each menu.

For this, the web.sitemap will be something like:
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
     <siteMapNode  url="~/" title="Home"  description="Home" visible="true">
         <siteMapNode url="" description="Menu 1" title="Menu 1" visible="true">
             <siteMapNode url="" description="SubMenu 1" title="Sub Menu 1" visible="true"/>
         </siteMapNode>
         <siteMapNode url="" description="Menu 2" title="Menu 2" visible="true"/>
         <siteMapNode url="" description="Menu 3" title="Menu 3" visible="true"/>
     </siteMapNode>
</siteMap>

Open in new window

The attribute "visible" is that we will indicate whether or not the menu is shown, and we'll add the event MenuItemDataBound on Menu with the following code:
protected void NavigationMenu_MenuItemDataBound(object sender, MenuEventArgs e)
{     SiteMapNode node = e.Item.DataItem as SiteMapNode;
     if (!string.IsNullOrEmpty(node["visible"]))
     {
         bool isVisible;
         if (bool.TryParse(node["visible"], out isVisible))
         {
             if (!isVisible)
             {
                 if (e.Item.Parent != null)
                     e.Item.Parent.ChildItems.Remove(e.Item);
                 else
                     ((Menu)sender).Items.Remove(e.Item);
             }
         }
     }
}

Open in new window

Thus, we have our menu to show all nodes whose attribute value equals True.

To be able to directly control the menus that will be visible or not, I used a Treeview to bind the web.sitemap file and set all items to show a checkbox, which will indicate the status of the Visible attribute.
<asp:TreeView runat="server" ID="tvMenus" AutoGenerateDataBindings="False" DataSourceID="XmlDsSiteMap"
     OnTreeNodeCheckChanged="tvMenus_TreeNodeCheckChanged" ShowCheckBoxes="All" ShowLines="True"
     OnTreeNodeDataBound="tvMenus_TreeNodeDataBound">
     <DataBindings>
         <asp:TreeNodeBinding DataMember="siteMapNode" SelectAction="None" ShowCheckBox="True"
             TextField="title" />
         <asp:TreeNodeBinding DataMember="siteMapNode" TextField="title" />
         <asp:TreeNodeBinding DataMember="siteMapNode" TextField="title" />
         <asp:TreeNodeBinding DataMember="siteMap" />
     </DataBindings>
</asp:TreeView>
<asp:XmlDataSource ID="XmlDsSiteMap" runat="server" DataFile="~/Web.sitemap" XPath="/*/*/*">
</asp:XmlDataSource>

 

protected void tvMenus_TreeNodeDataBound(object sender, TreeNodeEventArgs e)
{     XmlElement node = e.Node.DataItem as XmlElement;
     if (node.Attributes["visible"] != null)
     {         if (!string.IsNullOrEmpty(node.Attributes["visible"].Value))
         {
             bool isVisible;
             if (bool.TryParse(node.Attributes["visible"].Value, out isVisible))
             {
                 e.Node.Checked = isVisible;
             }
             else
                 e.Node.Checked = true;
         }
         else
             e.Node.Checked = true;
     }
}

Open in new window

menu2f.png
Finally, to record the attribute changes depending on the state of the checkbox, we added to the Treeview TreeNodeCheckChanged event the following code:
protected void tvMenus_TreeNodeCheckChanged(object sender, TreeNodeEventArgs e)
{     XmlDsSiteMap.GetXmlDocument().SelectSingleNode(e.Node.DataPath)
               .Attributes["visible"].Value = e.Node.Checked.ToString();
}

And we add the button to save the changes the following code:

protected void btn_Click(object sender, EventArgs e)
{     XmlDsSiteMap.Save();
}

Open in new window

Now just enable and disable these items like we want to.
 menu3x.png
This is a very simple way to allow your application users control each Menu visibility and avoid to change the web.sitemap manually.
You may have to make some changes in order to adjust to your requirements, but this is a good point.
1
Comment
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
0 Comments

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Join & Write a Comment

In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…

Keep in touch with Experts Exchange

Tech news and trends delivered to your inbox every month