Friday, December 2, 2005
UPDATE: Click here for new info on making both the main tab and sub-tab selected.
We’ve been playing around with the ASP.NET 2.0 SiteMap and Menu controls over the past few weeks, and have been quite impressed with them overall, though I have one major grievence...
What we’re trying to accomplish is the venerable Tab/SubTab layout:
We’ve got a custom control/ configuration reader that will accomplish this, but I figured I’d take a stab at using the built-in controls and auth stuff, to see how it goes.
The top set of tabs: “Home”, “Admin”, etc… are a simple menu tied to a sitemap data source…
<asp:Menu ID="menuMain" runat="server"
CssClass="Tabs"
DataSourceID="SiteMapDataSource1"
Orientation="Horizontal"
MaximumDynamicDisplayLevels="0">
<StaticHoverStyle CssClass="Hover" />
<StaticMenuItemStyle CssClass="Tab" />
<StaticSelectedStyle CssClass="Selected" />
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource1"
runat="server"
ShowStartingNode="False" />
The first thing to notice is that we’ve set MaximumDynamicDisplayLevels="0" on the menu. We don’t want it to show any sub-menu’s at this point, so hide them. Also, we’ve set the SiteMapDataSource to NOT show the starting node. Sitemap files can only have ONE ROOT NODE, “Home” or something like that. Everything else comes below that. We’re skipping that in our menu so that we first see all of the second level sitemap nodes.
Now, to create the second row of tabs, we create our content area, and put ANOTHER menu tied to a different SiteMapDataSource ….
<div class="Content">
<asp:Menu ID="menuSub" runat="server"
CssClass="SubTabs"
DataSourceID="SiteMapDataSource2"
Orientation="Horizontal">
<StaticHoverStyle CssClass="Hover" />
<StaticMenuItemStyle CssClass="Tab" />
<StaticSelectedStyle CssClass="Selected" />
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource2"
runat="server"
ShowStartingNode="False"
StartingNodeOffset="1" />
<asp:ContentPlaceHolder ID="Club" runat="server">
</asp:ContentPlaceHolder>
</div>
There’s a couple of things of interest here…
First, the SiteMapDataSource has StartingNodeOffset="1" , which will tell it to skip the row that the main tabs have already shown. Again, we tell it also to not show the starting node.
Second, you can see we’re using master pages here. We simply place our ContentPlaceHolder within our content div, and the other pages will replace out accordingly.
I suppose it’s appropriate to show the sitemap file at this point, though there’s nothing special going on.
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="..." >
<siteMapNode url="" title="Home" description="">
<siteMapNode url="~/Default.aspx" title="Home" />
<siteMapNode url="~/Admin.aspx" title="Admin">
<siteMapNode url="~/ManageInstructors.aspx"
title="Manage Instructors" />
<siteMapNode url="~/ManageLocations.aspx"
title="Manage Locations" />
</siteMapNode>
.
.
.
</siteMapNode>
</siteMap>
The main thing to notice is that we’re skipping the Root Node of the sitemap.
With the appropriate STYLES… (download the StyleSheet.css file HERE), we now have a working set of tabs!!!
Well, sort of… the one thing that you may notice, (and my major issue with this method), is that there is no way for the sub-tabs of the menu to leave their parent tab highlighted…
What we REALLY are looking for is this: (photoshopped.. *sigh*)
Sadly, I don’t have an answer for this… Well I do, but not with utilizing the ASP.NET menu control. We have, however written a Tabs Control of our own, which takes this into account. In a few days, I will post an entry talking about that control.
Dusty Davidson
Lead Developer