-[Danny Chen]- Blog of an ASP.NET QA tester

Tips and info about Site Navigation, ImageMap, Menu and other cool ASP.NET v2.0 features.

Hacking the SiteMapPath, changing it's data source.

The SiteMapPath control is designed to work directly against a SiteMapProvider.  However, there is sometimes that rare
occasion where a developer might want to take advantage of the formatting of a SiteMapPath but take the data from somewhere
other than a SiteMapProvider (such as another control).  In that case, obviously, the developer would be inclined to build a
custom control that inherits from SiteMapPath.  However, since the SiteMapPath works directly with a provider and not with a
datasource, the process seems trickier.  This MSDN help article helps describes some of the process:

http://msdn2.microsoft.com/en-us/library/system.web.ui.webcontrols.sitemappath.createcontrolhierarchy.aspx

As mentioned in the article, there are two primary places a developer is likely to override.  InitializeItem where completely
custom rendering can be injected and CreateControlHierarchy where the controls are generated.  This article will focus on
CreateControlHierarchy because that is what needs to be overridden to change the data feed.

The purpose of CreateControlHierarchy is to take the data from a source (normally a SiteMapProvider) and convert it into a
series of SiteMapNodeItem controls which are added to the Controls collection of the SiteMapPath.  In the process, InitializeItem
is called on each item which populates it with any templating/style information that has been set.  It also is responsible for firing any
Databinding and Creation events. 

Here's an example of a custom CreateControlHierarchy function which takes it's data from a TreeView.  The idea in this case is to
take a populated TreeView with a selected node and render out a path from the root of the tree to that node.  There's a link to a
working control listing at the end of the article.

        Protected Overrides Sub CreateControlHierarchy()
            
Dim item As SiteMapNodeItem = Nothing

            ' Get the current selected tree node
            If Tree Is Nothing Then
                Throw New Exception("Tree or TreeViewID is not valid")
            
End If
            Dim node As TreeNode = Tree.SelectedNode()
            
If node Is Nothing Then
                Return
            Else
                ' Create the current node
                AddItemFromTreeNode(item, node, SiteMapNodeItemType.Current)
                node = node.Parent

                
' Create the parent nodes and separators
                While node IsNot Nothing AndAlso node.Parent IsNot Nothing
                    AddItemFromTreeNode(item, Nothing, SiteMapNodeItemType.PathSeparator)
                    AddItemFromTreeNode(item, node, SiteMapNodeItemType.Parent)
                    node = node.Parent
                
End While

                ' Create the root node (unless there is only one node)
                If node IsNot Nothing Then
                    AddItemFromTreeNode(item, Nothing, SiteMapNodeItemType.PathSeparator)
                    AddItemFromTreeNode(item, node, SiteMapNodeItemType.Root)
                
End If
            End If
        End Sub

The function AddItemFromTreeNode will add SiteMapNodeItems to the Controls collection that reflect the passed in
TreeNode.  The code itself is very straight forward, add the current node, any number of parent nodes, and then the root node, all
the while looping through the parent node hierarchy of the TreeView.

 Link to VB Code Listing

Comments

flora said:

Does this work for the master page?

# January 9, 2008 5:27 AM

michaelg said:

Can I use the Menu control data instead of the TreeView data ? If yes, how ?

Thanks.

# January 29, 2008 4:05 PM
Leave a Comment

(required) 

(required) 

(optional)

(required)