ASP.NET 2.0 TreeView without Postback? Solved!


I've been scratching my head at the ASP.NET 2.0 TreeView control.  This control is meant to show a tree of items and each item can have a link to it.  For example, this is what I use for my menu on the left of the page. 

It works great, except I had a specific case where I wanted to use it.  I have a form for data entry where there is a hierarchy of items to select from.  The user picks an item from the tree view and I read the Path of the TreeView control and store it as the selected item.  This worked but everytime the user selected an item, I was getting a post-back to the server. It was as if   AutoPostback had been enabled.  But the TreeView control doesn’t have an AutoPostback property.  I noticed that if I set the node’s NavigateUrl property that clicking on a node didn’t call __DoPostBack, but instead called the URL I specified in the NavigateUrl property. So I decided to make the NavigateUrl property “javascript:void(0)”.  Essentially telling it that when the item is clicked, do nothing.

But it didn’t work.  What was happening was that the control expected to navigate away from the current page, so selecting the item in the control did not matter.  It simply ignored the “selection” process.

It was time to dig out Lutz Roeder’s Reflector to see what the TreeView was doing. I dove pretty deep into the actual rendering code of each node.  I thought I was stuck or perhaps was going to having to cruft up some nasty hack using reflection to specify a NagivateUrl that would do the selection for me. That’s when I saw it.  In the code, if you specify a Target for the node (or the entire TreeView) it will make the Selection code happen.  

Why does it do this?  It works this way because if the Target of the NavigateUrl is not the current page (e.g. Target=_blank or Target=SomeFrame), then the page isn’t going to change.  Therefore, it needs to mark the current item as selected.  

This left me a hacky way to my solution.  I would specify the Target=”_self”, and NavigateUrl=”javascript:void(0)”. For example:

<asp:TreeView ID="TreeView1"

              runat="server"

              Target="_self">

  <Nodes>

    <asp:TreeNode Text="One"

                  NavigateUrl="javascript:void(0)" >

      <asp:TreeNode Text="Two"

                    NavigateUrl="javascript:void(0)" />

    </asp:TreeNode>

  </Nodes>

  <SelectedNodeStyle Font-Bold="True" />

</asp:TreeView>

 

Not an elegant solution, but a workable one.

 

Caveat:

  • All or nothing!  You can't have some nodes with a server-style select and others with the javascript:void(0) select.  Otherwise the control gets confuses who is really selected.

 

 




Application Name WilderBlog Environment Name Production
Application Ver 1.1.0.0 Runtime Framework .NETCoreApp,Version=v1.1
App Path D:\home\site\wwwroot Runtime Version .NET Core 4.6.24628.01
Operating System Microsoft Windows 6.2.9200 Runtime Arch X86