views:

3552

answers:

7

I have an asp.net 2.0 page that contains 2 UpdatePanels.

The first panel contains a TreeView control, when I select a node in the three view control it triggers an update of the second UpdatePanel only. This much is behaving correctly.

There are two buttons on the page outside of an update panel (previous/next). These buttons trigger an update of both panels. The behaviour of the buttons is to select the adjacent node in the tree. The first time I click on one of these buttons I get the expected behaviour, and adjacent node is selected and the both panels are updated to reflect this change.

The problem happens when I click any of these buttons again. The selected node of the treeview seems to remember the previously selected node and the buttons act on this node. So the behaviour of the previous/next buttons is to do nothing or jump back two.

Edit - Sample code that demonstrates my problem

The markup

 <asp:UpdatePanel ID="myTreeViewPanel" runat="server">
    <ContentTemplate>
       <asp:TreeView runat="server" ID="myTreeView" OnSelectedNodeChanged="myTreeView_SelectedNodeChanged">
          <SelectedNodeStyle BackColor="#FF8000" />
       </asp:TreeView>
    </ContentTemplate>
    <Triggers>
       <asp:AsyncPostBackTrigger ControlID="myButton" EventName="Click" />
    </Triggers>
 </asp:UpdatePanel>
 <asp:UpdatePanel ID="myLabelPanel" runat="server">
    <ContentTemplate>
       <asp:Label runat="server" ID="myLabel" Text="myLabel"></asp:Label>
    </ContentTemplate>
    <Triggers>
       <asp:AsyncPostBackTrigger ControlID="myTreeView" EventName="SelectedNodeChanged" />
       <asp:AsyncPostBackTrigger ControlID="myButton" EventName="Click" />
    </Triggers>
 </asp:UpdatePanel>
 <asp:Button runat="server" ID="myButton" Text="myButton" OnClick="myButton_Click" />

The code behind

   protected void Page_Load ( object sender, EventArgs e )
   {
      if ( !IsPostBack )
      {
         myTreeView.Nodes.Add( new TreeNode( "Test 1", "Test One" ) );
         myTreeView.Nodes.Add( new TreeNode( "Test 2", "Test two" ) );
         myTreeView.Nodes.Add( new TreeNode( "Test 3", "Test three" ) );
         myTreeView.Nodes.Add( new TreeNode( "Test 4", "Test four" ) );
         myTreeView.Nodes.Add( new TreeNode( "Test 5", "Test five" ) );
         myTreeView.Nodes.Add( new TreeNode( "Test 6", "Test size" ) );
      }
   }
   protected void myTreeView_SelectedNodeChanged ( object sender, EventArgs e )
   {
      UpdateLabel( );
   }
   protected void myButton_Click ( object sender, EventArgs e )
   {
      // here we just select the next node in the three
      int index = myTreeView.Nodes.IndexOf( myTreeView.SelectedNode );
      myTreeView.Nodes[ index + 1 ].Select( );
      UpdateLabel( );
   }
   private void UpdateLabel ( )
   {
      myLabel.Text = myTreeView.SelectedNode.Value;
   }

It is like the viewstate of the tree is not being saved?

A: 

Sorry... Without the code I can drop only a single tip: Debug!

Skubs
I have added the source code can you have another look?
tpower
A: 

I think you're right about the AJAX partial page postback that it doesn't update the hidden input __ViewState.

I have the same thing with my update panels when a user navigates back to the pages in my website application form. The normal inputs have updated the viewstate and so their values are repopulated but the state of the controls that were updated with AJAX isn't recorded and so they revert to the default state.

Dave Anderson
A: 

I can fix this problem by saving and restoring the selected node in the pages own view state, by just added these two functions.

protected override object SaveViewState()
{
   ViewState["SelectedNodePath"] = myTreeView.SelectedNode.ValuePath;
   return base.SaveViewState();
}

protected void Page_PreLoad(object sender, EventArgs e)
{
   if (ViewState["SelectedNodePath"] != null)
   {
      TreeNode node = myTreeView.FindNode(ViewState["SelectedNodePath"].ToString());
      if (node != null)
         node.Select();
   }
}

I can't load the selected the node inside LoadViewState() because the tree doesn't have any nodes at that point. So I do it in PreLoad.

It just feels wrong that I have to do this. Am I missing something?

tpower
+1  A: 

From UpdatePanel Control Overview [asp.net]

Controls that Are Not Compatible with UpdatePanel Controls

The following ASP.NET controls are not compatible with partial-page updates, and are therefore not supported inside an UpdatePanel control:

  • TreeView and Menu controls.
  • ...
Robert Paulson
A: 

Why not try another Ajax Framework, I think our TreeView is way cooler than the ASP.NET version, and it's way faster...

Thomas Hansen
@Thomas: I've noticed that a lot of your posts get flagged as spam, and for moderator attention. It might help if you *explicitly* mention in your posts about ra-ajax that it's free and open source, and explain how it solves the problem the OP is asking about. Once sentence posts that contain a link really do look like spam. It might also help if you were to link to the Google Code project page instead of your .org, but that's just my opinion.
Bill the Lizard
A: 

Hi all,

I found this post very useful. I could very easily get the fix for SelectedNode by putting the same into the viewstate.

However I have a different problem. I am not getting the checkedNodes collection properly. It gives me the values some times and not sometimes.

I shall be detailing the behaviour very soon. Meanwhile, if anybody could help me, please lend a helping hand.

Regards, Kangkan

Kangkan
A: 

I am facing almost a similar issue. I loose the CheckedNodes collection. I doubt the same technique will solve my issues. Any idea?

Kangkan