TreeView子节点填充问题

use*_*312 4 c# treeview

我需要从复合数据库表构建一个巨大的树视图Grouping.

Grouping是,我们在SQL Server Management Studio Express中看到的.一个后Database节点,一些固定的文件夹都显示(如,Database Diagrams,Tables,Views,Synonyms,ProgrammabilitySecurity)和儿童在这些文件夹中进行分组.

到目前为止,我已经使用AfterSelect事件和处理程序来实现这一目标.

但问题AfterSelect是,在选择节点之前,观众无法知道是否有任何可用的孩子.这是因为,可展开的plus标志不可见.

我想用BeforeExpand.但问题BeforeExpand是,如果已经填充了孩子,它就有效.在这种情况下,当我点击组时,没有任何反应.

怎么解决这个?

所以代码/网络链接将不胜感激.

Fre*_*örk 12

我通常做的是在可能存在应该以懒惰方式加载的子项的地方添加"虚拟子节点".这将使父级具有加号,然后您可以将代码添加到AfterExpand事件中,执行以下操作:

  • 检查是否只有一个子节点,如果该子节点是虚节点(可以使用Tag属性来标识虚节点)
  • 如果找到虚拟节点,则启动搜索以获取子节点并将其添加到父节点,通过删除虚节点来完成它.

我通常给虚拟节点一个文本,如"正在加载数据.请稍候......",以便用户获得有关正在发生的事情的信息.

更新
我把一个简单的例子放在一起:

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; }
}
Run Code Online (Sandbox Code Playgroud)