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.

 

 



Shawn
Shawn Wildermuth
Author, Teacher, and Coach




My Courses

Wilder Minds Training
Vue.js by Example (New Lower Price)
Bootstrap 4 by Example (New Lower Price)
Intro to Font Awesome 5 (Free Course)
Pluralsight
Building an API with ASP.NET Core (New Course)
Building a Web App with ASP.NET Core, MVC6, EF Core, Bootstrap and Angular (updated for 2.2)
Less: Getting Started (New)
Using Visual Studio Code for ASP.NET Core Projects
Implementing ASP.NET Web API

Application Name WilderBlog Environment Name Production
Application Ver v4.0.30319 Runtime Framework x86
App Path D:\home\site\wwwroot\ Runtime Version .NET Core 4.6.27817.01
Operating System Microsoft Windows 10.0.14393 Runtime Arch X86