We've had various feature requests come in for the site navigation feature to include additional built in properties. This got turned down because it wasn't really useful data about a Site Map Node and because it was easily done through the extensibility features. In general this will work for any custom attribute but I'll show examples for target since it's the most commonly requested.
First, lets start with a simple web.sitemap and add a custom attributes that we'll want to map to target. Web.sitemap allows for custom attributes to be added to each SiteMapNode. They can be accessed later by the indexer property, for example:
Here's an example web.sitemap:
Now add a menu or treeview to the page bound to the SiteMapDataSource. In order to make this work, we'll subscribe to the Item/Node databound event.
And here is the code that makes it work:
But what about SiteMapPath? It's less common that this would want to be done for a SiteMapPath but that doesn't mean we shouldn't able to do it. Lets see... Well, it does have an itemDataBound event...
First, lets start with a simple web.sitemap and add a custom attributes that we'll want to map to target. Web.sitemap allows for custom attributes to be added to each SiteMapNode. They can be accessed later by the indexer property, for example:
Dim someNode As SiteMapNode = GetMyNode()Dim value As String = someNode("value")
or
SiteMapNode someNode = GetMyNode();string value = someNode["value"];
<?xml version="1.0" encoding="utf-8" ?>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Home.aspx" title="Home" target="_blank">
<siteMapNode url="Work.aspx" title="Work" target="_bottom" />
<siteMapNode url="School.aspx" title="School" target="_top" />
</siteMapNode>
</siteMap>
<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >
<siteMapNode url="Home.aspx" title="Home" target="_blank">
<siteMapNode url="Work.aspx" title="Work" target="_bottom" />
<siteMapNode url="School.aspx" title="School" target="_top" />
</siteMapNode>
</siteMap>
Now add a menu or treeview to the page bound to the SiteMapDataSource. In order to make this work, we'll subscribe to the Item/Node databound event.
<%@ Page Language="VB" AutoEventWireup="true"
CodeFile="Default.aspx.vb"
Inherits="_Default" EnableViewState="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server"> <title>My Page</title>
</head>
<body> <form id="form1" runat="server"> <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" /> <asp:Menu ID="Menu1" runat="server"
DataSourceID="SiteMapDataSource1"
OnMenuItemDataBound="Menu1_MenuItemDataBound"> </asp:Menu> <asp:TreeView ID="TreeView1" runat="server"
DataSourceID="SiteMapDataSource1"
OnTreeNodeDataBound="TreeView1_TreeNodeDataBound"> </asp:TreeView> </form>
</body>
</html>
CodeFile="Default.aspx.vb"
Inherits="_Default" EnableViewState="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server"> <title>My Page</title>
</head>
<body> <form id="form1" runat="server"> <asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" /> <asp:Menu ID="Menu1" runat="server"
DataSourceID="SiteMapDataSource1"
OnMenuItemDataBound="Menu1_MenuItemDataBound"> </asp:Menu> <asp:TreeView ID="TreeView1" runat="server"
DataSourceID="SiteMapDataSource1"
OnTreeNodeDataBound="TreeView1_TreeNodeDataBound"> </asp:TreeView> </form>
</body>
</html>
And here is the code that makes it work:
Partial Class Default Inherits System.Web.UI.Page
Protected Sub TreeView1_TreeNodeDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) _
Handles TreeView1.TreeNodeDataBound
e.Node.Target = CType(e.Node.DataItem, SiteMapNode)("target")
End Sub
Protected Sub Menu1_MenuItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.MenuEventArgs) _
Handles Menu1.MenuItemDataBound
e.Item.Target = CType(e.Item.DataItem, SiteMapNode)("target")
End Sub
End Class
Protected Sub TreeView1_TreeNodeDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) _
Handles TreeView1.TreeNodeDataBound
e.Node.Target = CType(e.Node.DataItem, SiteMapNode)("target")
End Sub
Protected Sub Menu1_MenuItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.MenuEventArgs) _
Handles Menu1.MenuItemDataBound
e.Item.Target = CType(e.Item.DataItem, SiteMapNode)("target")
End Sub
End Class
But what about SiteMapPath? It's less common that this would want to be done for a SiteMapPath but that doesn't mean we shouldn't able to do it. Lets see... Well, it does have an itemDataBound event...
Protected Sub SiteMapPath1_ItemDataBound(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.SiteMapNodeItemEventArgs) _
Handles SiteMapPath1.ItemDataBound
If e.Item.ItemType = SiteMapNodeItemType.Parent Or _
e.Item.ItemType = SiteMapNodeItemType.Root Then If e.Item.Controls(0).GetType().ToString = _
"System.Web.UI.WebControls.HyperLink" Then
CType(e.Item.Controls(0), System.Web.UI.WebControls.HyperLink).Target = _
e.Item.SiteMapNode("target")
End If End If End Sub
But it isn't very nice. There are a lot of things to worry about, is the item a parent or root or is the child control actually a link. I'm not even checking any of the other possible child controls either. A much better way to do this would be to use the templating. Notice the databinding against custom attributes using [key].ByVal e As System.Web.UI.WebControls.SiteMapNodeItemEventArgs) _
Handles SiteMapPath1.ItemDataBound
If e.Item.ItemType = SiteMapNodeItemType.Parent Or _
e.Item.ItemType = SiteMapNodeItemType.Root Then If e.Item.Controls(0).GetType().ToString = _
"System.Web.UI.WebControls.HyperLink" Then
CType(e.Item.Controls(0), System.Web.UI.WebControls.HyperLink).Target = _
e.Item.SiteMapNode("target")
End If End If End Sub
<asp:SiteMapPath ID="SiteMapPath1" runat="server"> <NodeTemplate> <asp:HyperLink ID="HyperLink1" runat="server"
Target='<%# Eval("[target]") %>'
NavigateUrl='<%# Eval("url") %>'
ToolTip='<%# Eval("description") %>'> <%#Eval("title")%>
</asp:HyperLink> </NodeTemplate>
</asp:SiteMapPath>
Target='<%# Eval("[target]") %>'
NavigateUrl='<%# Eval("url") %>'
ToolTip='<%# Eval("description") %>'> <%#Eval("title")%>
</asp:HyperLink> </NodeTemplate>
</asp:SiteMapPath>
No comments:
Post a Comment