代码之家  ›  专栏  ›  技术社区  ›  user366312

TreeView子节点填充问题

  •  4
  • user366312  · 技术社区  · 15 年前

    我需要用 Grouping .

    分组 是,我们在SQL Server Management Studio Express中看到的。后一 Database 节点,显示一些固定文件夹(例如, Database Diagrams ,请 Tables , Views , Synonyms , Programmability Security )子级被分组到这些文件夹中。

    到目前为止,我一直在使用 AfterSelect 实现这一点的事件和处理程序。

    但问题是 后选择 是,在选择节点之前,查看器无法知道是否有可用的子级。这是因为,可扩展的 plus 标志不可见。

    我想用 BeforeExpand . 但问题是 预扩张 也就是说,如果已经填充了子对象,它就会工作。在这种情况下,当我单击Groups时,不会发生任何事情。

    如何解决这个问题?

    因此,我们将感谢您提供代码/网络链接。

    2 回复  |  直到 14 年前
        1
  •  13
  •   Fredrik Mörk    15 年前

    我通常要做的是添加一个“虚拟子节点”,无论哪里可能有需要以懒惰的方式加载的子节点。这将使父级具有加号,然后可以向AfterExpand事件添加代码,在其中执行以下操作:

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

    我通常给虚拟节点一个类似“加载数据”的文本。请稍候……”左右,以便用户了解正在发生的情况。

    更新
    我举了一个简单的例子:

    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; }
    }
    
        2
  •  0
  •   Community CDub    8 年前

    树在每个文件夹/组前面显示“+”是标准的行为,单击时会显示“+”,如果发现没有孩子,这就省去了昂贵的“有孩子吗”检查。

    或者,如果您有一种确定节点是否有子节点的廉价方法,则可以提供此信息。 This question 提供更多信息。