A customized TreeView navigation control. For example, the NodeWrap has been set to True (it is False by default):
<div class="ms-quicklaunchouter" runat="server"> <div class="ms-treeviewouter"> <SharePoint:SPRememberScroll runat="server" id="RememberScroll1" onscroll="javascript:_spRecordScrollPositions(this);" style="width: 220px;"> <Sharepoint:SPTreeView runat="server" id="TreeView1" ShowLines="false" DataSourceId="TreeViewDataSource1" ExpandDepth="0" SelectedNodeStyle-CssClass="ms-tvselected" NodeStyle-CssClass="ms-navitem" NodeStyle-HorizontalPadding="2" SkipLinkText="" NodeIndent="8" ExpandImageUrl="/_layouts/images/tvclosed.png" ExpandImageUrlRtl="/_layouts/images/tvclosedrtl.png" CollapseImageUrl="/_layouts/images/tvopen.png" CollapseImageUrlRtl="/_layouts/images/tvopenrtl.png" NoExpandImageUrl="/_layouts/images/tvblank.gif" NodeWrap="True"> </Sharepoint:SPTreeView> </Sharepoint:SPRememberScroll> </div> </div> <SharePoint:SPHierarchyDataSourceControl runat="server" id="TreeViewDataSource1" RootContextObject="Web" ShowFolderChildren="true" IncludeDiscussionFolders="false"/>
A minimal SPTreeView control:
<SharePoint:SPTreeView ID="TreeView1" DataSourceID="TreeViewDataSource1" runat="server" /> <SharePoint:SPHierarchyDataSourceControl runat="server" id="TreeViewDataSource1" RootContextObject="Web" ShowFolderChildren="true" IncludeDiscussionFolders="false"/>
TreeNodeDataBound event:
// Reference namespaces. using System.Web.UI; using System.Web.UI.WebControls; using Microsoft.SharePoint; using Microsoft.SharePoint.Navigation; using Microsoft.SharePoint.WebControls; public partial class TestPage : LayoutsPageBase { protected void Page_Load(object sender, EventArgs e) { // Register an event handler. TreeView1.TreeNodeDataBound += new TreeNodeEventHandler(TreeView1_TreeNodeDataBound); // Bind to a data source in order to invoke the TreeView1_TreeNodeDataBound event handler. TreeView1.DataBind(); } // Implement the TreeView1_TreeNodeDataBound event handler. protected void TreeView1_TreeNodeDataBound(object sender, TreeNodeEventArgs e) { IHierarchyData d1 = (IHierarchyData)e.Node.DataItem; // ... use IHierarchyData properties: HasChildren, Item, Path, Type. ISPHierarchyData d2 = (ISPHierarchyData)e.Node.DataItem; // ... use ISPHierarchyData properties: EncodedName, ImageUrl, IsContextListNode, // Name, NavigateUrl, ServerRelativeUrl. } }
IHierarchyData and ISPHierarchyData interfaces:
public interface IHierarchyData { // Methods IHierarchicalEnumerable GetChildren(); IHierarchyData GetParent(); // Properties bool HasChildren { get; } object Item { get; } string Path { get; } string Type { get; } } public interface ISPHierarchyData { // Properties string EncodedName { get; } string ImageUrl { get; } bool IsContextListNode { get; } string Name { get; } string NavigateUrl { get; } string ServerRelativeUrl { get; } }
Populating SPTreeView (TreeView1) recursively with sites and subsites:
protected void Page_Load(object sender, EventArgs e) { BuildTree(SPContext.Current.Site); } private void BuildTree(SPSite site) { TreeView1.Nodes.Clear(); foreach (SPWeb web in site.RootWeb.Webs) { AddSitesAndLists(web, null); web.Dispose(); } foreach (SPList list in site.RootWeb.Lists) { if (!list.Hidden) { TreeNode node = new TreeNode(list.Title, null, null, list.DefaultViewUrl, "_self"); foreach (SPListItem folder in list.Folders) { TreeNode folderNode = new TreeNode(folder.Name, null, null, site.RootWeb.Url + "/" + folder.Url, "_self"); node.ChildNodes.Add(folderNode); } TreeView1.Nodes.Add(node); } } } private void AddSitesAndLists(SPWeb web, TreeNode parentNode) { TreeNode node = new TreeNode(web.Title, null, null, web.Url, "_self"); if (parentNode == null) TreeView1.Nodes.Add(node); else parentNode.ChildNodes.Add(node); parentNode = node; foreach (SPWeb subsite in web.Webs) { AddSitesAndLists(subsite, parentNode); subsite.Dispose(); } foreach (SPList list in web.Lists) { if (!list.Hidden) { node = new TreeNode(list.Title, null, null, list.DefaultViewUrl, "_self"); parentNode.ChildNodes.Add(node); foreach (SPListItem item in list.Folders) { if (item.Folder != null) { TreeNode folderNode = new TreeNode(item.Folder.Name, null, null, web.Url + "/" + item.Folder.Url, "_self"); node.ChildNodes.Add(folderNode); } } } } }
A result of the above recursive procedure may look like that: