Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
198 views
in Technique[技术] by (71.8m points)

c# - TreeView child node populating problem

I need to construct a huge treeview from a composite database table with Grouping.

Grouping is, what we see in SQL Server Management Studio Express. After a Database node, some fixed folders are shown (like, Database Diagrams, Tables, Views, Synonyms, Programmability and Security) and children are grouped in those folders.

Up to this point I have used AfterSelect event and handler to achieve this.

But the problem with AfterSelect is, before selecting the node, the viewer is not able to know whether there is any child available. This is because, the expandable plus sign is not visible.

I want to use BeforeExpand. But the problem with BeforeExpand is, it works if the children are already populated. In that case, when I click groups, nothing happens.

How to solve this?

So codes/web-link will be appreciated.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What I usually do is to add a "dummy child node" wherever there may be children that should be loaded in a lazy manner. This will make the parent have the plus sign, and then you can add code to the AfterExpand event where you do the following:

  • Check if there are are exactly one child, and if that child is the dummy node (you can use the Tag property to identify the dummy node)
  • If the dummy node is found, launch a search to get the children and add them to the parent node, finish it off by removing the dummy node.

I typically give the dummy node a text like "Loading data. Please wait..." or so, so that the user gets some info on what is going on.

Update
I put together a simple example:

public class TreeViewSample : Form
{
    private TreeView _treeView;
    public TreeViewSample()
    {
        this._treeView = new System.Windows.Forms.TreeView();
        this._treeView.Location = new System.Drawing.Point(12, 12);
        this._treeView.Size = new System.Drawing.Size(200, 400);
        this._treeView.AfterExpand +=
            new TreeViewEventHandler(TreeView_AfterExpand);
        this.ClientSize = new System.Drawing.Size(224, 424);
        this.Controls.Add(this._treeView);
        this.Text = "TreeView Lazy Load Sample";
        InitializeTreeView();
    }

    void TreeView_AfterExpand(object sender, TreeViewEventArgs e)
    {
        if (e.Node.Nodes.Count == 1 && e.Node.Nodes[0].Tag == "dummy")
        {
            // this node has not yet been populated, launch a thread
            // to get the data
            ThreadPool.QueueUserWorkItem(state =>
            {
                IEnumerable<SomeClass> childItems = GetData();
                // load the data into the tree view (on the UI thread)
                _treeView.BeginInvoke((Action)delegate
                {
                    PopulateChildren(e.Node, childItems);
                });
            });
        }
    }

    private void PopulateChildren(TreeNode parent, IEnumerable<SomeClass> childItems)
    {
        TreeNode child;
        TreeNode dummy;
        TreeNode originalDummyItem = parent.Nodes[0];
        foreach (var item in childItems)
        {
            child = new TreeNode(item.Text);
            dummy = new TreeNode("Loading. Please wait...");
            dummy.Tag = "dummy";
            child.Nodes.Add(dummy);
            parent.Nodes.Add(child);
        }
        originalDummyItem.Remove();
    }

    private IEnumerable<SomeClass> GetData()
    {
        // simulate that this takes some time
        Thread.Sleep(500);
        return new List<SomeClass>
        {
            new SomeClass{Text = "One"},
            new SomeClass{Text = "Two"},
            new SomeClass{Text = "Three"}
        };
    }

    private void InitializeTreeView()
    {
        TreeNode rootNode = new TreeNode("Root");
        TreeNode dummyNode = new TreeNode("Loading. Please wait...");
        dummyNode.Tag = "dummy";
        rootNode.Nodes.Add(dummyNode);
        _treeView.Nodes.Add(rootNode);
    }
}

public class SomeClass
{
    public string Text { get; set; }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...