Just in case in the future someone is looking to make the Accordion control into a sitemap also I am going to post my final code. Well, it's probably not completely final, but its working beatifully and it looks freakin awesome! Sorry for the lack of comments in the code.
The AccordianSiteMap_Load() is called during the Page_Load event and parses the SiteMap collection to fill the Accordion panes.
The AccordionSiteMap_OpenCurrentPane(), also called from Page_Load, opens the current pages pane in the Accordian control when the current page changes. It does this with the help of RootIndexofCurrentNode() which searches through the SiteMap collection to determine which pane the current page belongs to. A warning about this function though, if your SiteMap tree is very deep this function might slow your page load times down. It is a recursive function so depending on the depth of your sitemap the times will vary. My SiteMap is only 3 levels deep and the time isn't even noticeable.
Also, I'd like to say, I haven't done any programming in quite a long time (3 years) and I am quite proud of myself for remembering how to code recursion (compiled and ran properly on first try), but if anyone has any suggestions or spots a mistake anywhere in my code please let me know!
' HTML
<cc1:Accordion ID="AccordionSiteMap" runat="server" AutoSize="none"
FramesPerSecond="24" RequireOpenedPane="false" SuppressHeaderPostbacks="true"
TransitionDuration="500" HeaderCssClass="AccordionHeader" ContentCssClass="AccordionContent">
</cc1:Accordion>
' VB CODE
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
AccordionSiteMap_Load(sender, e)
AccordionSiteMap_OpenCurrentPane(sender, e)
End Sub
Protected Sub AccordionSiteMap_Load(ByVal sender As Object, ByVal e As EventArgs)
Dim p As New AjaxControlToolkit.AccordionPane
Dim linkClass, currentLinkClass, nonCurrentLinkClass As String
linkClass = ""
currentLinkClass = "AccordionCurrentLink"
nonCurrentLinkClass = "AccordionLink"
If SiteMap.RootNode.HasChildNodes Then
Dim RootNodesEnumerator As IEnumerator = SiteMap.RootNode.ChildNodes.GetEnumerator()
Dim paneCounter As Integer = 0
While RootNodesEnumerator.MoveNext
p = Nothing
p = New AjaxControlToolkit.AccordionPane
p.ID = "Pane" & Regex.Replace(RootNodesEnumerator.Current.ToString(), "\s+", "")
p.HeaderContainer.Controls.Add(New LiteralControl("<span>" & RootNodesEnumerator.Current.Title & "</span>"))
If RootNodesEnumerator.Current.HasChildNodes Then
Dim ChildNodesEnumerator As IEnumerator = RootNodesEnumerator.Current.ChildNodes.GetEnumerator()
While ChildNodesEnumerator.MoveNext
If SiteMap.CurrentNode Is Nothing Then
linkClass = nonCurrentLinkClass
ElseIf SiteMap.CurrentNode.ToString = ChildNodesEnumerator.Current.ToString Then
linkClass = currentLinkClass
Else
linkClass = nonCurrentLinkClass
End If
p.ContentContainer.Controls.Add(New LiteralControl("<a class='" & linkClass & "' "))
p.ContentContainer.Controls.Add(New LiteralControl("href='" & ChildNodesEnumerator.Current.url & "'>"))
p.ContentContainer.Controls.Add(New LiteralControl(ChildNodesEnumerator.Current.title & "</a>"))
End While
End If
AccordionSiteMap.Panes.Add(p)
End While
End If
End Sub
Protected Sub AccordionSiteMap_OpenCurrentPane(ByVal sender As Object, ByVal e As EventArgs)
If SiteMap.CurrentNode Is Nothing Then
AccordionSiteMap.SelectedIndex = -1
Else
AccordionSiteMap.SelectedIndex = RootIndexofCurrentNode(SiteMap.RootNode.ChildNodes)
End If
End Sub
Private Function RootIndexofCurrentNode(ByVal Nodes As SiteMapNodeCollection) As Short
Dim index As Short = -2
If Nodes Is Nothing Then
RootIndexofCurrentNode = -1
ElseIf Nodes.Contains(SiteMap.CurrentNode) Then
RootIndexofCurrentNode = Nodes.IndexOf(SiteMap.CurrentNode)
Else
For Each n As SiteMapNode In Nodes
index = RootIndexofCurrentNode(n.ChildNodes)
If index <> -1 Then
If n.ParentNode.ToString = SiteMap.RootNode.ToString Then
Return SiteMap.RootNode.ChildNodes.IndexOf(n)
Else
Return index
End If
End If
Next
Return -1
End If
'CSS
div[id*="AccordionSiteMap"] {font-family: Times;
text-align: center;
width: 200px;
margin: 0;
padding: 0;
overflow: hidden !important;
}
.AccordionHeader + div {
position: relative;
z-index: 1;
top: -5px;
}
.AccordionHeader {
background: url(Images/AccordionHeader.png) no-repeat;
height: 30px;
position: relative;
z-index: 10;
margin-top: 5px;
}
.AccordionHeader span {
display: block;
color: #DDDDDD;
font-weight: bold;
text-decoration: none;
font-variant: small-caps;
line-height: 30px;
letter-spacing: .2em;
}
.AccordionHeader span:hover {
color: white;
font-weight: 500;
cursor: pointer;
}
.AccordionContent {
width: 180px;
margin: 0 auto;
border-bottom: 2px solid black;border-right: 2px solid black;
}
.AccordionContent > a {
display: block;
white-space: nowrap;
border-top: 1px solid black;
padding: 1px 0;
background: url(Images/AccordionContent.png) repeat-y;
}
.AccordionContent > a:first-child {
border-top: none !important;
height: 22px;
line-height: 22px;
}
.AccordionContent > a:hover {
background: url(Images/AccordionContentOver.png) repeat-y;
color: White;
}
.AccordionLink {
color: Black;
}
.AccordionCurrentLink {
color: Maroon;
}
Here's a screenshot of what it looks like. I don't have the site online yet so this is the best I can do. And ignore the dumb content in the main window.
SCREENSHOT1