Hide a Parent Node in TreeView if there is No ChildNodes

Scenario:

Say you have a TreeView that is populated based on the logged-in user role. There could be case when there are no chilc nodes for a particular parent node because user does not have access to the pages under that node. So in that case a parent node will appear without any child-nodes. What we want to do is we want to hide a node if it does not have any child nodes and that node is not a Leaf node (Note: Leaf nodes don't have childnodes).

Background:

 I have a TreeView and SiteMapDatasource on my .aspx page. Web.config has siteMapProvider settings and a SiteMap file (Web.sitemap).

Now let the code speak.

.aspx file:

<asp:TreeView ID="TreeView1" runat="server" AutoGenerateDataBindings="False" DataSourceID="SiteMapDataSource1"

ontreenodedatabound="TreeView1_TreeNodeDataBound">

</asp:TreeView>

<br />

<asp:SiteMapDataSource ID="SiteMapDataSource1" runat="server" />

Above is .aspx file with controls for this example. You should note we have a event handler for OnTreeNodeDataBound event of TreeView.

Web.config:

<siteMap defaultProvider="XmlSiteMapProvider" enabled="true"> <providers>

<add name="XmlSiteMapProvider" type="System.Web.XmlSiteMapProvider"

siteMapFile="Web.siteMap" securityTrimmingEnabled="true"/> </providers>

</siteMap>

Part of web.config is shown above with SiteMapProvider. Note we have siteMapFile="Web.sitemap"  and securityTrimmingEnabled="true" for Roles to be applied to the sitemap.

Web.SiteMap:

<siteMap xmlns="http://schemas.microsoft.com/AspNet/SiteMap-File-1.0" >

<siteMapNode url="~/Default.aspx" title="Home" description="Home">

<siteMapNode url="~/Level1.aspx" title="Level 1" description="" >

<siteMapNode url="~/Page1.aspx" title="Page1" description="" />

<siteMapNode url="~/Page2.aspx" title="Page2" description="" />

</siteMapNode>

<siteMapNode url="~/NoChilde.aspx" title="Level 2" description="" />

<siteMapNode url="~/Level3.aspx" title="Level 3" description="" >

<siteMapNode url="~/Page3.aspx" title="Page3" description="" />

</siteMapNode>

</siteMapNode>

</siteMap>

The above sitemap is not very realistic looking but will serve the purpose for our demonstration. We see that siteMapNode "Level 2" does not have any childnode. So we want to hide it and not show in our TreeView. In real case scenario it might have few child nodes with Roles attribute set. If user is not in particular role the SiteMapProvider will hide those node.

Without the code-behind which we are going to see in a moment the TreeView will look like below:

treeView1

We now want to hide "Level 2" node as it does not have any child node.

.aspx.cs file (code-behind):

protected void TreeView1_TreeNodeDataBound(object sender, TreeNodeEventArgs e)

{

SiteMapNode node = (SiteMapNode)e.Node.DataItem;

if(node.HasChildNodes ==false && e.Node.Depth ==1)

{

TreeView1.Nodes[0].ChildNodes.Remove(e.Node);

 

}

}

In the above code what we are doing is first getting the DataItem for the CurrentNode that is being DataBound. For this we have to use SiteMapNode.

1: we check if the node has Child with node.HasChildNodes ==false.

2: "Home" is at Depth 0 while Level 1,2 and 3 are at Depth 1 and Page1,Page2 and so on are at Depth=2. So to make sure that we are not hiding Home or any leaf nodes (page1,Page2 etc) we are checking that depth of current Node is 1.

If the above two conditions are met then we will remove the current node (i.e. e.Node) from TreeView1.

For this we first get the NodesCollection for TreeView1. i.e. TreeView1.Nodes[0], Here 0 is because we have all Nodes under "Home" parent Node.

After that we call the ChildNodes.Remove method to remove the current Node.

That is it. Now if we run the code we will get the following output for TreeView:

treeview1

ShowStartingNode=False set for SiteMapDataSource:

 If you set the ShowStartingNode=False for SiteMapDataSource then you might want to chage the Depth=0 and also make little change on how to remove node.

The code should look like below:

protected void TreeView1_TreeNodeDataBound(object sender, TreeNodeEventArgs e)

{

SiteMapNode node = (SiteMapNode)e.Node.DataItem;

if(node.HasChildNodes ==false && e.Node.Depth ==0)

{

TreeView1.Nodes.Remove(e.Node);

}

}

Thats it. Thanks for reading this article.

4 Comments

  • This does work but how would you get protected void TreeView1_TreeNodeDataBound to fire if you have a tree view that is not data bound? &nbsp;I am wondering because, well, I have a tree view that is not data bound but rather gets it's nodes from a Folder on a intranet server.

  • SkyHandle,
    Sorry, I don't have an immediate answer to your question but..
    Do you mind posting your question with your code here: http://forums.asp.net/139.aspx
    Then post the link to your question here.

  • Nice post, But what if my child nodes, also have their own child nodes?
    How would i display that data?

  • ryafel,
    I did not understand the problem you are facing.
    This post is to hide a Parent node if there are no childnodes.

    Thanks.

Comments have been disabled for this content.