This is a migrated thread and some comments may be shown as answers.

Tree View on demand loading concept in 2011

12 Answers 245 Views
Treeview
This is a migrated thread and some comments may be shown as answers.
erwin
Top achievements
Rank 1
Veteran
Iron
erwin asked on 20 Mar 2011, 12:50 AM
How does the current NewNodesNeeded actually work?

Does the event handler get called for each visible node to determine if the expand hint (+) should be showed?
If yes, this is not a usable concept for me. I would like to give that indication without actually loading the children.

When I load my root nodes, I already know if they have children (by grouping and count() in the database).
The Idea now is to show the user how many children there are and let him decide if he wants to expand (and wait for the nodes to be loaded).

Regards Erwin

12 Answers, 1 is accepted

Sort by
0
Julian Benkov
Telerik team
answered on 23 Mar 2011, 04:22 PM
Hi Erwin,

The new NodesNeeded event is fired only when a node is in expanded state and its Nodes collection is empty. You can expand a node that is currently not into view programmatically and the visibility state of the node will not be taken into consideration by the event handler. This gives us good performance, decreased possible recursion issues and simplified API which only has the NodesNeeded event.

All the best,
Julian Benkov
the Telerik team
0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 23 Mar 2011, 04:47 PM
so how do you determine if the expand hint should be shown for a visible node (non expanded state) without calling the NodesNeeded Event?
0
Julian Benkov
Telerik team
answered on 24 Mar 2011, 03:26 PM
Hi erwin,

The NodesNeeded event is fired initially when RadTreeView is loaded. If the Parent property is null, this means that the event is fired for the root level, so we pass the desired root node(s) to the Nodes collection that comes from the event arguments. Further, the NodesNeeded is fired once again for each of the created root nodes even before we try to expand them. As a result, we load the children of the root nodes before we expand these root nodes and this is how the nodes know whether to show the expander or not. When we expand a root node, the NodesNeeded event is fired for each of the child nodes where we pass the children of the child nodes. So, the child nodes know whether to show the expander image or not as well.

We will consider extending the Load-On-Demand feature, showing the expander element for each node.

Best wishes,
Julian Benkov
the Telerik team

0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 24 Mar 2011, 05:03 PM
Julian,

that's exactly what I suspected. Unfortunately that makes the feature unusable for many scenarios. If you really care about performance, you can model the query so that when loading the root nodes, you already know if there are child nodes. That makes 1 roundtrip to the database instead of 30 or whatever visible root nodes you have.
In my scenario, the demand loading with NodesNeeded is most of the times much slower than loading the tree in one go with no on demand loading at all, since that also requires just 1 roundtrip to the database. The thing is, that the round trip to a database including query parsing etc. is extremely expensive.
Not that much of an issue though, when you still provide a way to manually load nodes on expand events. But see my other post about display glitches with that approach..

regards
Erwin
0
Julian Benkov
Telerik team
answered on 29 Mar 2011, 03:10 PM
Hi Erwin,

I made also another solution of Load-On-Demand functionality using NodeExpandedChanged, CreateNode and NodeFormatting events:

public partial class Form6 : Form
{
    class LazyTreeNode : RadTreeNode
    {
        private bool loaded;
 
        public bool Loaded
        {
            get { return loaded; }
            set { loaded = value; }
        }
    }
 
    public Form6()
    {
        InitializeComponent();
        radTreeView1.ShowLines = true;
 
        using (radTreeView1.DeferRefresh())
        {
            for (int i = 0; i < 10; i++)
            {
                radTreeView1.Nodes.Add("RootNode" + i.ToString());
            }
        }
    }
 
    private void radTreeView1_NodeExpandedChanged(object sender, Telerik.WinControls.UI.RadTreeViewEventArgs e)
    {
        LazyTreeNode node = e.Node as LazyTreeNode;
        if (node.Loaded)
        {
            return;
        }
 
        node.Nodes.BeginUpdate();
        for (int i = 0; i < 10; i++)
        {
            node.Nodes.Add("ChildNode" + i.ToString());
        }
        node.Nodes.EndUpdate();
        node.Loaded = true;
    }
 
    private void radTreeView1_CreateNode(object sender, Telerik.WinControls.UI.CreateTreeNodeEventArgs e)
    {
        e.Node = new LazyTreeNode();
    }
 
    private void radTreeView1_NodeFormatting(object sender, TreeNodeFormattingEventArgs e)
    {
        e.NodeElement.ExpanderElement.Visibility = Telerik.WinControls.ElementVisibility.Visible;
    }
}

This solution has a known issue concerning the indent of the RadTreeNodes at the different levels. In Q1 2011 SP1 the desired behavior will be natively supported by RadTreeView, the layout issue will be addressed and the NodeNeeded event will be raised only the currently visible and expanded level.

Best wishes,
Julian Benkov
the Telerik team
0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 29 Mar 2011, 03:54 PM
Thanks, Julian. that's roughly the method I used with prior versions but which now prevents upgrading my solution because of the indent problem. Looking forward to SP1 then.

Regards
Erwin
0
Joel Kraft
Top achievements
Rank 2
answered on 14 Apr 2011, 08:51 PM
I would like to echo erwin's statement that this is not a usable concept in many circumstances (I too had implemented a similar lazy-load mechanism in previous versions).

Is there an ETA for SP1? Will a work-around similar to the one presented be required or will there be a property to set when the NewNodesNeeded event gets fired (on node displayed versus on node expanded)?
0
Julian Benkov
Telerik team
answered on 20 Apr 2011, 10:26 AM
Hi Joel,

You can download and use new Q1 2011 SP1 release. In the new improved implementation of load-on-demand functionality the NodesNeeded event is raised only for expanded parent node. This is the new default behavior of RadTreeView control, for other cases when you want to know the nodes for inner level in advance, then must set the new LazyMode property of treeview to false. We also added support to make RadTreeView work properly with the approach valid for the old version of RadTreeView control using Loaded property in this example:

public partial class Form4 : Form
{
    public Form4()
    {
        InitializeComponent();
        this.radTreeView1.NodesNeeded += new NodesNeededEventHandler(radTreeView1_NodesNeeded);
 
        using (radTreeView1.DeferRefresh())
        {
            for (int i = 0; i < 10; i++)
            {
                radTreeView1.Nodes.Add("RootNode" + i.ToString());
            }
        }
    }
 
    void radTreeView1_NodesNeeded(object sender, NodesNeededEventArgs e)
    {
         
    }
 
    private void radTreeView1_NodeExpandedChanged(object sender, Telerik.WinControls.UI.RadTreeViewEventArgs e)
    {
        LazyTreeNode node = e.Node as LazyTreeNode;
        if (node.Loaded)
        {
            return;
        }
 
        node.Nodes.BeginUpdate();
        for (int i = 0; i < 10; i++)
        {
            node.Nodes.Add("ChildNode" + i.ToString());
        }
        node.Nodes.EndUpdate();
        node.Loaded = true;
    }
 
    private void radTreeView1_CreateNode(object sender, Telerik.WinControls.UI.CreateTreeNodeEventArgs e)
    {
        e.Node = new LazyTreeNode();
    }
 
    class LazyTreeNode : RadTreeNode
    {
        private bool loaded;
 
        public bool Loaded
        {
            get { return loaded; }
            set { loaded = value; }
        }
    }
}

I hope this helps.

All the best,
Julian Benkov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 20 Apr 2011, 11:51 AM
Thanks, Julian.

I checked with the most trivial tree in my app and seems to work quite well.
In other trees I'll have to work a bit on the load logic.

I guess the release notes for SP1 should mention this as a breaking change compared to 2011Q1.

Regards
Erwin
0
Mydatafactory
Top achievements
Rank 1
answered on 04 May 2011, 07:58 AM
Hello,

When I use the new NodesNeedes event, I get 2 events when I start filling the root tree.
Both e arguments have the e.parent set to null.

Another question: When I use this event, I cannot dermine which node is calling the event.
What I want is load the root three when the app starts, each created root node will call the nodesneeded event, so I can determine if I need to fill his nodes collection with nodes.
But right now, when the nodesneeded event runs, I cannot deterine this.

Can you please help?
Regards,
Jeroen
0
erwin
Top achievements
Rank 1
Veteran
Iron
answered on 04 May 2011, 09:16 AM
Jeroen,

I do exaclty what you want to do with loading the root nodes when the control loads and loading child nodes on demand.

If the parent is null, I just ignore the NodesNeeded handler.

If the parent node is not null, I use it's Tag Property, where I previously stored the key to load child nodes.

hope this helps.

Erwin
0
Julian Benkov
Telerik team
answered on 06 May 2011, 11:55 AM
Hello A. Bennen,

Like Erwin suggested, you can load root nodes outside the event handler and use the event for the internal Nodes collection:
public partial class Form16 : Form
{
    public Form16()
    {
        InitializeComponent();
 
        //root Nodes
        for (int i = 0; i < 50; i++)
        {
            RadTreeNode childNode = new RadTreeNode(string.Format("Node{0}", i));
            this.radTreeView1.Nodes.Add(childNode);
        }
    }
 
    private void radTreeView1_NodesNeeded(object sender, Telerik.WinControls.UI.NodesNeededEventArgs e)
    {
        if (e.Parent == null)
        {
            return;
        }
 
        for (int i = 0; i < 50; i++)
        {
            RadTreeNode childNode = new RadTreeNode(string.Format("Node{0}", i));
            e.Nodes.Add(childNode);
        }
    }
}

 


Kind regards,
Julian Benkov
the Telerik team
Q1’11 SP1 of RadControls for WinForms is available for download; also available is the Q2'11 Roadmap for Telerik Windows Forms controls.
Tags
Treeview
Asked by
erwin
Top achievements
Rank 1
Veteran
Iron
Answers by
Julian Benkov
Telerik team
erwin
Top achievements
Rank 1
Veteran
Iron
Joel Kraft
Top achievements
Rank 2
Mydatafactory
Top achievements
Rank 1
Share this question
or