2008-09-23 65 views
8

我有一个用C#编写的遗留应用程序,它显示了一个非常复杂的树状视图,包含10到20万个元素。C中的慢树视图#

在过去,我遇到了一个类似的问题(但在C++中),我用Win32 API提供的OWNERDATA功能解决了这个问题。

C#中是否有类似的机制?

编辑:该计划是优化创建时间以及浏览时间。通过Win32 API可用的方法在这两种情况下都非常出色,因为它将初始化时间减少到无,并且元素的请求数量仅限于任何时候可见的元素数量。 Joshl:我们实际上正在按照你的建议做,但我们仍然需要更高的效率。

回答

6

虽然.NET的DataGridView支持这种类型的模型(请参阅DataGridView的VirtualMode属性),但我不相信.NET TreeView支持您想要的内容。 TreeView会让你绘制自己的节点,但它不会让你从一些虚拟商店中填充它们。

如果可能,您可能需要考虑为您的应用程序使用DataGridView。如果没有,那么手动管理节点(如上面的joshl提到的)可能会起作用,如果您可以解决一些问题,那么在扩展节点时正确刷新屏幕。除此之外,您可能想要查看一些第三方供应商,如this one (Divelements SandGrid),这可能会(强调可能)支持您所需的操作模式。

注:SandGrid不Divelements支持截至7月底的2013

19

提高性能的一种技术是在用户扩展树视图时加载TreeNodes。通常情况下,用户不需要同时在屏幕上打开20,000个节点。只需加载用户需要查看的级别以及需要向用户正确显示可供选择的任何子级信息(如果存在子项,扩展图标等,则展开图标)。随着用户扩展节点,及时加载孩子。

来自Keith的有用提示:使用winforms TreeView,您至少需要一个子节点,否则它不会显示扩展[+],但是您接着处理TreeNodeExpanded事件以删除该虚拟节点并填充子节点。

+1

延迟加载...我相信这被称为。很好的答案。 – Gishu 2008-09-23 14:23:36

+0

这个答案显然很好,它已经在我身边执行了。 – 2008-09-23 14:27:53

4

有使TreeView控件进行更好的一个方法,那就是创建所有子节点和钩在一起然后将节点添加到TreeView。如果这是我们正在谈论的图形性能。

TreeView tree = new TreeView(); 
TreeNode root = new TreeNode("Root"); 
PopulateRootNode(root); // Get all your data 
tree.Nodes.Add(root); 

否则,通过使用OnTreeNodeExpanded节点加载它们节点。

7

注:此答案由提问者说,他已经做这种事情的编辑无效,但我还是决定由其他人对这个话题

当我搜索仍然张贴以供将来参考我过去做过类似的事情,我倾向于选择天真的懒惰加载样式。

  • 使用TreeNode.Tag属性来保存,你可以用它来查找孩子
  • 使用TreeView.BeforeExpand事件来填充子节点
  • 可以选择使用TreeView.AfterCollapse事件删除它们的引用。
  • 为了让[+]/[ - ]框出现,我发现的最好方法是创建一个单身虚拟假人TreeNode,它作为一个孩子添加到所有未填充的节点,并且在填充之前检查它的存在与BeforeExpand
1

对于Windows C#编程中的大数据,无论是在WPF还是WinForms中,我都会动态地添加节点。我加载最初的树根+儿童+孙辈。当任何节点展开时,我加载代表扩展节点的孙子的树节点(如果有的话)。

该模式也适用于数据检索。如果您确实从数千或数百万条记录的数据源加载数据,则可能不希望先加载这些数据。没有用户希望等待加载,并且没有理由加载可能永远不会被查看的数据。

我通常在后台线程上根据需要加载孙子或孙辈子节点数据,然后将这些数据封送回UI线程并创建并添加节点。这使UI响应。您可以在视觉上装饰树节点以指示它们仍在加载,以便用户在您的IO之前到达数据存储。

8

在我们的主要WinForm的应用程序,我们有一个TreeView加载都在同一个镜头:

  • 的BeginUpdate()
  • 负载20.000节点
  • EndUpdate()

到目前为止表现还是不错的。它实际上是我们没有用第三方替代的少数几个组件之一。

根据我的经验,当您在不调用Begin/EndUpdate()的情况下加载节点(一次性或按需)时,TreeView性能变慢,特别是如果您的节点已排序,但如果调用Begin/EndUpdate )正确,你不应该真的得到与组件本身相关的性能问题。