在 .NET 中延迟加载 TreeView

Posted

技术标签:

【中文标题】在 .NET 中延迟加载 TreeView【英文标题】:Deferred loading of TreeView in .NET 【发布时间】:2010-10-22 10:42:28 【问题描述】:

这是一个 System.Windows.Forms.TreeView,而不是 WPF 或 Web TreeView。

我一定是错过了什么,因为我不敢相信这有那么难。

我的表单上有一个 TreeView。加载所有数据以填充 TreeView 非常慢,因此我只想加载***节点,然后在用户展开节点时填充子节点。问题是,如果一个节点没有任何子节点,它不会在节点旁边显示 + 号,这意味着它无法展开,这意味着我不能 捕获 Expanding 事件以加载子项。

几年前,当我使用 PowerBuilder 时,您会将 HasChildren(或类似的)属性设置为 true,以本质上对控件“撒谎”并强制它显示 +,然后您可以捕获 Expanding 事件。当没有子节点时,我无法弄清楚如何强制 + 出现在节点上。

我尝试了一种方法,我向每个节点添加一个虚拟节点,然后扩展检查虚拟节点是否存在并将其删除,然后加载子节点,但由于各种原因,不值得在这里讨论解决方案在我的情况下不可行。

我已经在 Google 上搜索了 c#、treeview、delayed、deferred、load、force、expansion 和其他一些术语的各种组合,但现在没有运气。

附:我在 SourceForge 上找到了 TreeViewAdv 项目,但如果可以避免的话,我宁愿不将新组件引入我们的环境。

【问题讨论】:

我一直使用虚拟节点法;它通常工作得很好。你能告诉我们更多关于它为什么不适合你的信息吗? 【参考方案1】:

一种可能的解决方案是领先于树视图一步:

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));
    

【讨论】:

【参考方案2】:

我也想知道如何让 + 出现在无子节点旁边,但我从来没有找到一个好方法。我的解决方案是像这样处理 MouseDoubleClick 事件:

Private Sub tvwMain_MouseDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tvwMain.MouseDoubleClick
    Dim oNode As TreeNode

    oNode = tvwMain.GetNodeAt(e.X, e.Y)

    If oNode IsNot Nothing Then
        If oNode.Nodes.Count = 0 Then
            'add children here
        End If
    End If
End Sub

【讨论】:

【参考方案3】:

我同意克里斯的观点,我不得不做这件不同的事情。加载顶部节点,然后捕获点击事件,确保点击是在选定节点上,然后填充该节点,最后展开它。

如果需要加号,则加载顶部节点并在其中放置一个虚拟节点。确保捕获单击或展开事件,清除节点然后重新填充它。

【讨论】:

我支持虚拟节点的想法。我自己使用它并将 Tag 属性设置为特定值,以将“正在加载...”虚拟节点与其他虚拟节点区分开来。在 BeforeExpand 中,我检查虚拟节点是否存在并替换内容。它对我很有效。【参考方案4】:

您是否尝试在 BeginUpdate()EndUpdate() 调用中包含您的节点添加?这会禁用任何绘制,因此允许您将大量节点添加到 TreeView,而不会产生明显的延迟。

MSDN: TreeView.BeginUpdate Method

【讨论】:

我认为 OP 意味着加载数据本身(例如从数据库)很慢,而不是添加树节点,所以他们想按需加载数据(当用户扩展每棵树时)节点)。 卢卡斯的评论是正确的。 TreeView 本身的填充速度足够快,但它获取的数据很慢。【参考方案5】:

在启动时加载前 2 个级别,在节点展开时加载 2 个级别。

【讨论】:

【参考方案6】:

使用 TreeViewAdv(在 sourceforge 上)可能会更好。

【讨论】:

以上是关于在 .NET 中延迟加载 TreeView的主要内容,如果未能解决你的问题,请参考以下文章

asp.net EF学习系列----深入理解查询延迟加载技术

ASP.NET Mvc开发之EF延迟加载

jQuery Lazy Load 图片延迟加载

延迟加载

深入理解 MVC .net 中的延迟加载和处理错误

(VIP-朝夕教育)2021-06-05 .NET高级班 35-延迟加载详解