Multi Level ASP.NET Menu with CSS Friendly Control AdaptersBuilding the New Code Camp Web Site (Part 2)
Monday 19 May 2008 @ 3:38 pm

Article Series

(Source Code Available in Article 6 Below - (Added March 2009))

Article 1: Best Practices for Building an ASP.NET quality web site
Article 2:

Multi Level ASP.NET Menu with CSS Friendly Control Adapters

Article 3:

Creating a Theme For Each Year of Code Camp Using Skins in ASP.NET

Article 4: Creating a Modal Login Window Using the Telerik Modal RadWindow Component
Article 5: Using LINQ to Merge Mailing Lists and Filter Opt Outs
Article 6: The Source Code!!! (Visual Studio Solution)

 

Introduction

It’s often the case that brilliant designers will make interfaces that are hard
to implement using standard frameworks like ASP.NET.  As Software engineers
striving for consistency, we always want to do the best we can with the standard
tool kits to take advantage for built in functionality. 
ASP.NET 2.0’s built in menu system
is a perfect example.  If you use that menu system, you get to make very simple
declarative site maps by simply using the
ASP.NET
2.0 Site Navigation Features.

The requirement faced today has to do with building the web site for our
third annual code
camp
.  We have that brilliant designer I mentioned above, and he has made
a design that just seems too perfect to compromise.  Here are some screen shots
of how the designer envisions the sight looking and working after it is completed.



css1



css2



css3



css4



css5

Notice the interesting behavior of the top menu (REGISTER;PROGRAM;NEWS;ABOUT
AND WIKI).  Unselected, the bottom line strip is the same as selected. 
When selected, the background of the selection changes to a different shade of the
same color as the bottom strip.

Also notice the interesting behavior of the secondary menu. that is, when ABOUT
is selected from the top menu, notice that the secondary menu shows: Contact;Venue;Organizers;Sponsors
and Previous.  As you can see above (on the bottom of the 5 pictures), when
Venu is selected, it is highlighted to in bright white to indicate that you have
selected that.  The really cool part here is that the ABOUT on the primary
menu stays highlighted when you choose different  secondary menu choices.

Why Go Through The Trouble, why not just do it with HTML and CSS directly

So, a reasonable person might say that since you can’t easily get this behavior
with the asp:menu control and the site map provider (OK, at least I couldn’t figure
it out), why not just code this up with simple list items, button clicks and a pile
of code to react to those things?  Well, the answer is you can certainly do
that.  The problem is the next time you want to do something similar you will
find yourself doing a lot of cut and pasting.  Personally, whenever I find
myself cutting and pasting a lot I know I should probably think about how to refactor
the code to make it more reusable and therefore more reliable.

What Are the Benefits of Using asp:menu and the site map providers

I mentioned that there are benefits to using the asp:menu and site map providers. 
What are those benefits you might ask.  Well, let me first show you what you
have to do to set up a simple menu system using these, then list the benefits of
what comes out.

 

The Web.SiteMap

First, you need to create a web.sitemap file in your web directory.  Here
is what a simple one looks like similar to what will create the pictures above.

   1:  <?xml version="1.0" encoding="utf-8" ?>


   2:  <siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >


   3:      <siteMapNode url="Default.aspx" title="HOME"  


   4:                   description="Silicon Valley CodeCamp 08">


   5:        <siteMapNode url="Register.aspx" title="REGISTER"  description="" />


   6:        <siteMapNode url="News.aspx" title="NEWS"  description="" />


   7:        <siteMapNode url="About.aspx" title="ABOUT"  description="">


   8:          <siteMapNode url="Contact.aspx" title="Contact"  description="" />


   9:          <siteMapNode url="Sponsors.aspx" title="Sponsors"  description="" />


  10:          <siteMapNode url="Previous.aspx" title="Previous"  description="" />


  11:        </siteMapNode>


  12:      </siteMapNode>


  13:  </siteMap>

The Web.Config

You need to declare which sitemap provider you are using. In our case, we are
simply reading from a file.  Then, you should (do not have to) declare a section
for each web page you want to provide role access to.  Here is an example of
my web.config.

This first part says give access to any logged in user for Sponsors.aspx

   1:  <location path="Sponsors.aspx">


   2:          <system.web>


   3:              <authorization>


   4:                  <deny users="?"/>


   5:              </authorization>


   6:          </system.web>


   7:      </location>


   8:  </configuration>


 


 

The Second part defines the Site Map Provider and sets securityTrimming to
true to only show pages the user has access to.

 


 
   1:  <system.web>


   2:          <siteMap defaultProvider="XmlSiteMapProvider" enabled="true">


   3:              <providers>


   4:                  <add name="XmlSiteMapProvider" 


   5:               description="SiteMap provider which reads in .sitemap XML files." 


   6:               type="System.Web.XmlSiteMapProvider, System.Web, Version=2.0.0.0,... 


   7:               siteMapFile="web.sitemap" securityTrimmingEnabled="true"/>


   8:              </providers>


   9:          </siteMap>

The Master Page

In your master page, you need to define your primary menu.  In our case,
it is the one that displays: REGISTER;NEWS and ABOUT.  Here is all you need
for that.

   1:  <asp:Menu ID="mainMenu" runat="server" Orientation="Horizontal" 


   2:      DataSourceID="SiteMapMain" CssClass="headLinksBar"  CssSelectorClass="SimpleEntertainmentMenu"


   3:      MaximumDynamicDisplayLevels="0" StaticItemFormatString="// {0} &nbsp;&nbsp;&nbsp; ">


   4:  </asp:Menu>


   5:  <asp:SiteMapDataSource ID="SiteMapMain" runat="server" ShowStartingNode="False" />


   6:   


   7:          

The Inherited Page (About.aspx For Example)

   1:  <asp:Content ID="SublinksSessions" ContentPlaceHolderID="Sublinks" runat="server">


   2:      <asp:Menu ID="subMenu" runat="server" DataSourceID="SiteMapAbout" SkinID="subMenu"  CssClass="headLinksBar" 


   3:            CssSelectorClass="SimpleEntertainmentMenu"     >


   4:      </asp:Menu>


   5:  </asp:Content>

 

 

And the Benefits…

  • You have no .net code to write!
  • Adding new menu items as Primary or Secondary is easy
  • Security is completely taken care of
  • Menu Entries Automatically come and go based on User Permission

 

Not Using the
CSS Friendly Adapters

If you do not use the CSS Friendly Adapter library, the menu render using tables. 
Below is what the actual HTML looks like of the main menu if I remove the
CSS Friendly Adapters.

 


Code Snippet

0: <table>
1: <a href="#ctl00_mainMenu_SkipLink">
2: <img alt="Skip Navigation Links"
3:  src="/WebStyleOnly%20-%20Copy/WebResource.axd?d=G5"
4: width="0" height="0" style="border-width: 0px;" /></a><table id="ctl00_mainMenu"
5: class="headLinksBar ctl00_mainMenu_2"
6:  cssselectorclass="SimpleEntertainmentMenu"
7: cellpadding="0" cellspacing="0" border="0">
8: <tr>
9: <td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
10:  onkeyup="Menu_Key(this)"
11: id="ctl00_mainMenun0">
12: <table cellpadding="0" cellspacing="0" border="0" width="100%">
13: <tr>
14: <td style="white-space: nowrap;">
15: <a class="ctl00_mainMenu_1"
16:  href="/WebStyleOnly%20-%20Copy/Register.aspx">
17: // REGISTER
18:  </a>
19: </td>
20: </tr>
21: </table>
22: </td>
23: <td style="width: 3px;">
24: </td>
25: <td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
26:  onkeyup="Menu_Key(this)"
27: id="ctl00_mainMenun1">
28: <table cellpadding="0" cellspacing="0" border="0" width="100%">
29: <tr>
30: <td style="white-space: nowrap;">
31: <a class="ctl00_mainMenu_1"
32:  href="/WebStyleOnly%20-%20Copy/News.aspx">
33: // NEWS </a>
34: </td>
35: </tr>
36: </table>
37: </td>
38: <td style="width: 3px;">
39: </td>
40: <td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)"
41:  onkeyup="Menu_Key(this)"
42: id="ctl00_mainMenun2">
43: <table cellpadding="0" cellspacing="0" border="0" width="100%">
44: <tr>
45: <td style="white-space: nowrap;">
46: <a class="ctl00_mainMenu_1"
47:  href="/WebStyleOnly%20-%20Copy/About.aspx">// ABOUT
48:  </a>
49: </td>
50: </tr>
51: </table>
52: </td>< /span>
53: </tr>
54: </table>

 

 

The same code, when using the
CSS Friendly adapters,
plus some clever additions that will be discussed later, has the html code looking
like the following.


Code Snippet

0: <table>
1: <tr>
2: <div class="AspNet-Menu-Horizontal">
3: <ul class="AspNet-Menu">
4: <li class="AspNet-Menu-TopLevel-register">
5: <a href="/WebStyleOnly - Copy/Register.aspx">
6: REGISTER</a> </li>
7: <li class="AspNet-Menu-TopLevel-news"><a
8:  href="/WebStyleOnly - Copy/News.aspx">NEWS</a>
9: </li>
10: <li class="AspNet-Menu-TopLevel-about-Selected">
11: <a href="/WebStyleOnly - Copy/About.aspx">
12: ABOUT</a> </li>
13: </ul>
14: </div>
15: </tr>
16: </table>

 

You can see that the CSS adapter code is not only much smaller, but easier to
read and because of the inserted class names, much easier to customize.

 

Conclusions

We have not made clear yet how the CSS Friendly Adapters will make the menu’s
work the way we want it to. We have shown css classes created (AspNet-Menu-TopLevel-about-Selected
for example) are create by the custom code written by us in the CSS Friendly Adapter
Project.  We have however talked about the menu control and showed an example
of how the html is actually rendered, and what is rendered based on.  That
is, the web.sitemap defines the menu and we have shown that.  In the next article,
we will show details of the custom code we have in the CSS Friendly Adapter that
solves the problem of how to highlight the menu choices based on what is clicked.

 

 





22 Responses to “Multi Level ASP.NET Menu with CSS Friendly Control AdaptersBuilding the New Code Camp Web Site (Part 2)”

  1. Chris Says:

    Hi Peter,

    Come across your article today and found out this is exactly what I’m trying to do at the moment. I’m using the CSS Friendly Menu with two Menu controls and two SiteMapDatasouce on Master, Content pages.

    I’m looking around the MenuAdapter.cs and not sure where to start of, will you possible give me some suggestions? Is you next article will be publishing soon?

    Best Regards,
    Chris

  2. Nancy Says:

    Hello Peter,
    I’m interested in finding out how to customize the menu adapter to include the name of the specific menu item in the class. For example ‘class=”AspNet-Menu-TopLevel-about-Selected”>’. How do you get it to add the ‘about’ part? Is there another part to this article that explains that?

    Thanks for your help,
    Nancy

  3. Peter Kellner Says:

    Nancy,
    I do plan a follow up post. Just have been busy lately.

  4. Harry Says:

    Hi, Peter

    This is just what I need to implement to my site.
    I was wondering.. if You can post the code for Venue.aspx and the codebehind.
    That’ll help me.

    Thanks
    Harry

  5. Jason Says:

    Hi Peter,

    I have the same question Nancy has. Any idea on when you’ll be able to post a solution for adding custom class names to the li elements?

    Thanks,
    Jason

  6. sara Says:

    Thank you Peter.

  7. chlorophyll Says:

    Very interesting article, so many useful informations,
    really good work!
    thx for nice reading

  8. Ian Says:

    Very good article, Although I’m still struggling to fully implement this, feel I’m missing the next step on how to customise the CSS classes. Sorry I’m not very experienced with ASP.NET. Could you give me any pointers.

    Thanks again
    Ian

  9. Yoyo Says:

    I don’t understand why and tags are used in the css menu in the second code snippet. What’s up with that?

  10. Yoyo Says:

    Oops!

    What I meant to say is:

    I don’t understand why table and tr tags are used in the css menu in the second code snippet. What’s up with that?

  11. admin Says:

    > I don’t understand why table and tr tags are used in the css menu in the second code snippet. What’s up with that?

    Hi Yoyo,

    I’m not a browser/css wizard, but the guy who helped me with the css said that using table solved some browser issues. I think it may have been an ie6 issue.

  12. coving Says:

    I will refer people to your ITEMS. Effective use of Wordpress had some exceptional.This looks good! Really good tutorial include so many helpful informations!

  13. Subhas Says:

    Hi Pete,
    It would be gr8 to post the helpful information on “Dynamic menu creation in Asp.net”. The menu items which i am using in my application is role specific; My question is ” storing the menu Items in database is good idea”.

    waiting for your reply.

    Thanks,
    Subhas

  14. Smitty Says:

    I appreciate your example, but I cannot get the sub menu styles working. Can you provide a download of the working app?

  15. admin Says:

    I don’t have a full working stand alone example yet. I’m hoping to make another post that will include that but have been pretty busy lately. Sorry. Maybe someone else has a working example of this.

  16. rubbish clearance london Says:

    Wow a fantastic site, I loved it when I landed on it. I could never do anything like this, maybe I should open a competition for someone to redesin mine. :-)

  17. anup Says:

    Hi,

    I m new to this control.
    I tried to implement but i cant get.
    Can you pleaz provide me Zip folder from which i download whole code.
    Thanks in advance.

  18. Kinny Says:

    Hi,
    I dont’t know how to set the SiteMapDataSource for SiteMapAbout.
    Thx.

  19. Ralph Says:

    I’ve installed and used CSSF. I set set propertied to display horizontally. But code created by CSSF is a list. UL. Which displays as a tree view. How do i display horizontally? Do I need to recode the menu by hand?

  20. Shujaat Says:

    Hi,

    I did try but failed to acheive any result, being new to asp.net. Please post a running code.

    Thanks

  21. admin Says:

    I just published the source code for these at this location: http://peterkellner.net/2009/03/27/codecampwebsiteseries6-cssfriendly-adapters-aspnet-menu/ -Peter

  22. Rob Hudson Says:

    So - the DataSource for SiteMapAbout, for example, is internally mapped by ASP.NET to the sitemap control’s “ABOUT” title’d node?

    Is the name of the data source derived from the node title?

Leave a Reply