Feed on

The new ASP.NET 2.0 TreeView control is pretty handy.  It can function as a normal treeview – where you can add/remove treenodes to the nodes collection. It can also serve as a site navigation tree.  In this mode each node on the tree becomes a hyperlink to another webpage.  The hyperlink gets its Href from the treenodes NavigationUrl property which in turn gets its Url from the web.sitemap file.

Today I finally solved one of the annoying dilemmas that crops up when using the Treeview.

The problem

A treenode can be selected or expanded.  Selecting the node causes the SelectedNodeChange event to fire if the Treeview is configured correctly.  Clicking the + icon on a node causes the TreeNodeExpanded event to fire.  The selected event will not fire if the node is in Navigation mode.    This behavior makes sense most of the time.  The node is acting  as a navigation link  – it causes the browser to take you to a new page which means there is no postback.  Your are going to a new page, without returning to the server first.

If the node has its NavigationUrl property set to an empty string, the node is in Selection mode.  If the NavigationUrl is a non-zero length string ,the node is in Navigation mode.

For our project I wanted the children nodes to expand whenever the user selects a parent node.  Yes, the user can click the + symbol to expand it,  but our testing showed that many users expect the node to expand by clicking the node text instead. Since the nodes are in Navigation mode I couldn’t  put the code in the SelectedNodeChanged event.

My solution?  Use the TreeNodeDatabound event to examine each node as it is being bound to the tree.  If the current page URL matches the treenode NavigationUrl I expand all the of the current nodes children.  It solves my problem.  It still doesn’t cause the SelectedNodeChanged to fire so it may not solve all your troubles. At least it’s a start.

Protected Sub treeMainMenu_TreeNodeDataBound _
           (ByVal sender As Object, _ 
ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) _
Handles treeMainMenu.TreeNodeDataBound
‘ other binding code here…
If Request.Url.PathAndQuery = e.Node.NavigateUrl Then
End If
End Sub



7/7/2006 9:04 AM EAI

Your code helped me indirectly. Thanks a lot.

7/8/2006 1:20 PM Martin

Thanks you code also helped me indirectly.
Saved quite some time.

Selection vs Navigation 7/19/2006 10:07 AM Alejandro Cifuentes

Thank you very much for your tips. I have made a change to your code. I need that a navigation node shows as an hyperlink, to expand the lower ones, so i modified the code to:
If e.Node.NavigateUrl = "" Then
e.Node.SelectAction = TreeNodeSelectAction.Expand
End If
Best regards,

8/17/2006 11:10 AM Andy

I used you code (thanks alot) and got this working in a demo project, but the more I played around with firing different events ans setting databindings … eventually it stopped working. No I cannot get it to work again. The TreeNodeDataBound event fires, and the call to expandAll() runs, but it does not expand. There seems to be a bunch of different properties in this control that force other properties to change to thier default, irrespective of what you set.
For example setting populateondemand in the databindings
<asp:TreeNodeBinding PopulateOnDemand=true
TextField="Title" NavigateUrlField="URL" />
or setting it in code in the TreeNodeDataBound event does not work.. must be overriden by another setting.
Anyone else experience this.

8/17/2006 11:31 AM Andy

Here is my code which no longer works. Where the TreeNodeDataBound event fires, and the call to expandAll() runs, but it does not expand.
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1" ExpandDepth="1"
protected void TreeView1_TreeNodeDataBound(object sender, System.Web.UI.WebControls.TreeNodeEventArgs e) {
if (Request.Url.PathAndQuery == e.Node.NavigateUrl) e.Node.ExpandAll();

8/17/2006 11:39 AM Andy

ok I remember I need PopulateNodesFromClient="false" in order to get the click on the text to navigate and expand.
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="SiteMapDataSource1" ExpandDepth="1"
OnTreeNodeDataBound="TreeView1_TreeNodeDataBound" PopulateNodesFromClient="false">

8/18/2006 10:42 AM Wendy

Thank You!! I have been searching for 2 days and have found tons of code but nothing that did exactly what I needed it to. This was just what I was looking for. Thanks a ton…

One Response to “Tip: ASP.NET 2.0 Treeview – Expanding Nodes when Bound to SiteMap”

  1. Partha Pratim Das says:

    Wow, i eventually found this after days of looking for a solution. Wonderful simple code!

Leave a Reply