views:

1917

answers:

2

I have an ASP.Net 2.0 page that contains two UpdatePanels. The first panel contains a TreeView. The second panel contains a label and is triggered by a selection in the tree. When I select a node the label gets updated as expected and the TreeNode that I clicked on becomes highlighted and the previously selected node is no longer highlighted. However if a node is original highlighted(selected) in the code-behind the highlight is not removed when selecting another node.

The markup

<asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
   <ContentTemplate>
      <asp:TreeView ID="TreeView1" runat="server" OnSelectedNodeChanged="TreeView1_SelectedNodeChanged">
         <SelectedNodeStyle BackColor="Pink" />
      </asp:TreeView>
   </ContentTemplate>
</asp:UpdatePanel>
<asp:UpdatePanel ID="UpdatePanel2" runat="server" ChildrenAsTriggers="True">
   <ContentTemplate>
      <asp:Label ID="Label1" runat="server" Text=" - "></asp:Label>
   </ContentTemplate>
   <Triggers>
      <asp:AsyncPostBackTrigger ControlID="TreeView1" EventName="SelectedNodeChanged" />
   </Triggers>
</asp:UpdatePanel>

The code behind

protected void Page_Load(object sender, EventArgs e)
{
   if (!IsPostBack)
   {
      TreeView1.Nodes.Add(new TreeNode("Test 1", "Test One"));
      TreeView1.Nodes.Add(new TreeNode("Test 2", "Test Two"));
      TreeView1.Nodes.Add(new TreeNode("Test 3", "Test Three"));
      TreeView1.Nodes.Add(new TreeNode("Test 4", "Test Four"));
      TreeView1.Nodes[0].Selected = true;
   }
}

protected void TreeView1_SelectedNodeChanged(object sender, EventArgs e)
{
   Label1.Text = TreeView1.SelectedValue;
}

The at the start the first node is selected. Why is its highlight not removed when selecting another node?

Also, I asked a different question about the same setup that I haven't got an answer for. Any help would appreciated.

Edit I know that setting ChildrenAsTriggers="false" will work but I want to avoid rendering the tree again as it can be very large.

A: 

You need to set the selection to false for all nodes.

I use something like this for one of my applications (with my treeview tvCategories):

public void RefreshSelection(string guid)
{
    if (guid == string.Empty)
        ClearNodes(tvCategories.Nodes);
    else
        SelectNode(guid, tvCategories.Nodes);

}

private void ClearNodes(TreeNodeCollection tnc)
{
    foreach (TreeNode n in tnc)
    {
        n.Selected = false;
        ClearNodes(n.ChildNodes);
    }
}
private bool SelectNode(string guid, TreeNodeCollection tnc)
{
    foreach (TreeNode n in tnc)
    {
     if (n.Value == guid)
     {
      n.Selected = true;
      return true;
     }
     else
     {
      SelectNode(guid, n.ChildNodes);
     }
    }

    return false;
}
Jason Kealey
But this happens at the server side. I don't want the panel that contains the tree to be updated.
tpower
I'm not regenerating the three here, just changing the selection, no?
Jason Kealey
A: 

This may be a bit of a hack but this will clear the selection on the client and avoid updating the panel.

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(function BeginRequestHandler(sender, args)
   {
      var elem = args.get_postBackElement();
      var selectedClassName = elem.id + '_1';

      var arrAllElements = GetElementsByClassName(selectedClassName, elem);
      var selectedNode = $get(elem.id + '_SelectedNode').value;

      for(var i = 0; i < arrAllElements.length; i++)
      {
         if(arrAllElements[i].childNodes[0].id != selectedNode)
            RemoveClassName(arrAllElements[i], selectedClassName );
      }
   }
);

It removes the selected style/class from all tree nodes unless its value is contained in the '_SelectedNode' hidden field. GetElementsByClassName and RemoveClassName are in my own js library but are obvious enough.

tpower