Home - Forums-.NET - FlyTreeView (ASP.NET) - Maintaining the collapsed/expanded state in a masterpage

FlyTreeView (ASP.NET)

Technical support and KB related to the FlyTreeView control

This forum related to following products: FlyTreeView for ASP.NET

Maintaining the collapsed/expanded state in a masterpage
Link Posted: 16-Aug-2007 03:49
Hello,

Like the topic states, how to achieve this? I populate my flytreeview on demand, and set the navigateURL property. Though, when clicked, the entire tree collapses.

I know this is an old issue, but there HAS to be a workaround for this in some way. I was thinking if you could somehow save the value of the node, and then find it after the redirect. However, your documentation does not help me on this matter.

The other option would be to somehow use client side code, however that seems too complicated. For instance to fetch the navigateUrl property with javascript and somehow \"load\" the new page in the masterpage.

What are my options here? is it possible at all?

Thanx!
Link Posted: 16-Aug-2007 03:59
Yes, there were similar request regarding the functionality you need.

The reason is simple - page is not posted back, but reloaded and then it has no state information from the previous page load (stored in viewstate + postback data).

There can be several workarounds possible.

You can store some identifier in the Value property and have additional parameter in NavigateUrl.

like node.Value = \"123\";
node.NavigateUrl = \"somepage.aspx?treenode=123\"

So next time you're loading treeview, you can use
treeview.FindByValue(Request.QueryString[\"123\"]);

then recursively set Expanded to True to all its parent nodes, and also set Selected to true (if required in your case).


The second option is to look though nodes using
treeview.Find(...) to find a node having NavigateUrl of the current Page request Url. And expand to it, etc.
Link Posted: 16-Aug-2007 04:05
Hi EvgenyT,

thanks for the input. I was thinking something similar, however I could not get my find-methods to work at all. Follow me here:

I populate my tree on demand from a database. Initially, there are only two nodes expanded:

Node 1
-- Node 2

Let's say the user expands some more levels:

Node 1
-- Node 2
---- Node 3
------ Node 4

And clicks node 4, and is redirected by the navigateUrl property. When the page is reloaded the tree is collapsed back to:

Node 1
-- Node 2

Hence my search for \"node 4\" is pointless, since it does not yet exist. Am I correct?

With this assumption it will not be possible to find my node.. Or am I wrong? You maybe assumed I used some kind of XML data source to bind the tree?

BR
Link Posted: 16-Aug-2007 05:13
Yes, in case of on demand populating, the things go wrong.

So alternatively you can store a path of values and pass it as a parameter.

Moreover, the FlyTreeNode class contains the Path property that is a joined string of nodes' values (see also the FlyTreeView.PathSeparator option).

So you can add it to the NavigateUrl as a parameter and use it to expand nodes from parent to child in the next page load.

P.S. Every time you expand some node, just use FlyTreeView.PopulateExpandedNodes() to make treeview populate currently expanded node. So you can use node.ChildNodes.FindByValue(valueForChild) again.
Link Posted: 16-Aug-2007 19:05
Hi EvgenyT,

thanks, you've been helpful. However, could you give me a short example on how to find my node if I have a path? Let's say the pathseparator is ';' and the path is: 1;2;3;4. How do I correctly find node with value 4 and expand all nodes before it?

That would save my day

BR
Link Posted: 16-Aug-2007 21:17
Like this

FlyTreeNodeCollection nodes = youtreeview.Nodes;
FlyTreeNode node;
string[] values = string.split(\"1;2;3;4\")
foreach(string v in values)
{
     node = nodes.FindByValue(v);
     node.Expanded = true;
     yourtreeview.PopulateExpandedNodes();
     nodes = node.ChildNodes;
}

The only think is that you do not need to expand the latest node (4) value. Just modify my code to skip this step.
Link Posted: 16-Aug-2007 22:17
[quote="EvgenyT"]Like this

FlyTreeNodeCollection nodes = youtreeview.Nodes;
FlyTreeNode node;
string[] values = string.split("1;2;3;4")
foreach(string v in values)
{
     node = nodes.FindByValue(v);
     node.Expanded = true;
     yourtreeview.PopulateExpandedNodes();
     nodes = node.ChildNodes;
}

The only think is that you do not need to expand the latest node (4) value. Just modify my code to skip this step.


Hi again,

that looks great. What I probably missed is the ChildNodes event. Makes sense. However, I get an error on the FindByValue method, since this method returns a collection and not a single node. Am I missing a cast?

Thankx! ;)
Link Posted: 17-Aug-2007 08:11
Yes, there is an error.
FindByValue returns FlyTreeNodeCollection and so you need to take the first element from it.
Link Posted: 19-Aug-2007 18:49
Hi,

I solved it. In case anyone else has the same issues:


FlyTreeNodeCollection nodes = TreeView.Nodes;
FlyTreeNodeCollection sn;

string[] values = PATH.Split(';');

foreach(string s in values)
{
       sn = nodes.FindByValue(s, true);

       foreach (FlyTreeNode ftn in sn)
       {
            ftn.Expanded = true;
            TreeView.PopulateExpandedNodes();
            nodes = ftn.ChildNodes;
       }
}


Thanks for your time, you've been most helpful.

Cheers!
Link Posted: 26-Aug-2007 19:58
Hm, I seem to be getting some strange behaviour from the code above after all. This is my code, placed in the page_load method:


if(Request.QueryString[\"path\"] != null)
{
    string PATH = Request.QueryString[\"path\"].ToString();

    FlyTreeNodeCollection nodes = TreeView.Nodes;
    FlyTreeNodeCollection sn;

    string[] values = PATH.Split(';');
    string lastNode = values[values.Length - 1];

    foreach(string s in values)
    {
           sn = nodes.FindByValue(s, true);

           foreach (FlyTreeNode ftn in sn)
           {
                ftn.Expanded = true;
                TreeView.PopulateExpandedNodes();
                nodes = ftn.ChildNodes;

                if (String.Equals(s, lastNode))
                {
                      ftn.Selected = true;
                }
           }
    }

    TreeView.FocusNode = TreeView.SelectedNode;
}


And everything seems to work fine when I navigate to a new page. The tree gets expanded correctly, the selected node gets selected AND focused.

However, everytime I make a postback in the new page, the tree seems to expand other nodes too. I checked the path to the \"extra\" nodes that get expanded, to the CORRECT node, and the path is different. I can't for the life of my understand why it does it. Can you see any error in my code above? Or is there some bug in the PopulateExpandedNodes() method perhaps?

Thankx.