Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deferred loading of TreeView in .NET

Tags:

.net

treeview

This is a System.Windows.Forms.TreeView, not a WPF or Web TreeView.

I must be missing something, because I can't believe this is that difficult.

I've got a TreeView on my form. Loading all the data to populate the TreeView is very slow, so I want to load just the top-level nodes and then fill in the children as the user expands nodes. The problem is, if a node doesn't have any children it doesn't display the + sign next to the node, which means it can't be expanded, which means I can't capture an Expanding event to load the children.

Years ago when I was using PowerBuilder you would set a HasChildren (or similar) property to true to essentially 'lie' to the control and force it to display the + and you could then capture the Expanding event. I've not been able to figure out how to force a + to appear on a node when there are no child nodes.

I've tried an approach where I add a dummy node to each node and then on expanding check if the dummy node is present and remove it then load the children, but for various reasons that aren't worth getting into here that solution is not viable in my situation.

I've Googled for various combinations of c#, treeview, delayed, deferred, load, force, expansion, and a few other terms that escape me now with no luck.

P.S. I found the TreeViewAdv project on SourceForge, but I'd rather not introduce a new component into our environment if I can avoid it.

like image 511
Craig W. Avatar asked Apr 28 '09 21:04

Craig W.


3 Answers

Load the first 2 levels at startup and load 2 levels down when a node is expanded.

like image 126
CSharper Avatar answered Oct 09 '22 22:10

CSharper


I agree with Chris, I've had to do this vary thing. Load the top nodes and then capture the click event, make sure the click was on a selected node, and then populate the node, and then finally expand it.

If it's required to have the plus, then load the top nodes and drop a dummy node in it. Make sure you capture the click or expand event, clear the nodes and then repopulate it.

like image 30
Joshua Belden Avatar answered Oct 09 '22 20:10

Joshua Belden


A possible solution is to stay one step ahead of the treeview:

private void Form1_Load(object sender, EventArgs e)
{
    // initialise the tree here
    var nodeSomething = treeView1.Nodes.Add("Something");
    nodeSomething.Nodes.Add("Something below something");

    treeView1.AfterExpand += AfterExpand;
}

private void AfterExpand(object sender, TreeViewEventArgs e)
{
    foreach (TreeNode node in e.Node.Nodes)
    {
        // skip if we have already loaded data for this node
        if (node.Tag != null) 
            continue;
        node.Tag = new object();
        node.Nodes.AddRange(GetDataForThisNode(node));
    }
}
like image 1
Dries Van Hansewijck Avatar answered Oct 09 '22 22:10

Dries Van Hansewijck