C#中的慢树视图

Fab*_*ure 9 c# optimization user-interface winforms

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

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

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

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

Jos*_*shL 20

一种提高性能的技术是在用户扩展树视图时加载TreeNodes.通常,用户不需要一次在屏幕上打开20,000个节点.仅加载用户需要查看的级别,以及正确显示用户可用性所需的任何子信息(如果存在子项,计数,图标等,则展开图标).当用户扩展节点时,及时加载子节点.

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


Fil*_*ini 11

在我们的主要WinForm应用程序中,我们一次性加载了一个树视图:

  • 的BeginUpdate()
  • 加载20.000个节点
  • EndUpdate()

到目前为止,性能仍然很好.它实际上是我们没有用第三方替换的少数组件之一.

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


Ken*_*ton 7

我不相信.NET TreeView支持你想要的东西,尽管.NET的DataGridView支持这种类型的模型(参见DataGridView的VirtualMode属性).TreeView将允许您绘制自己的节点,但它不允许您从某个虚拟商店填充它们.

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

注意:截至2013年7月底,Divelements不支持SandGrid.


Ale*_*man 7

注意:这个答案通过提问者编辑说他已经做过这种事情而无效,但我决定将其发布以供将来参考此主题的其他人参考

当我过去做过类似的事情时,我倾向于选择天真的懒人装载风格.

  • 使用该TreeNode.Tag属性可以保存可用于查找子项的引用
  • 使用该TreeView.BeforeExpand事件填充子节点
  • (可选)使用该TreeView.AfterCollapse事件删除它们.
  • 为了显示[+]/[ - ]框,我发现的最好方法是创建一个单独的虚拟对象TreeNode,作为子节点添加到所有未填充的节点,并在填充之前检查它是否存在BeforeExpand.


Seb*_*son 5

有一种方法可以使TreeView执行得更好,即创建所有子节点并将它们连接在一起,然后将节点添加到TreeView.如果这是我们正在讨论的图形性能.

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

否则,使用OnTreeNodeExpanded逐节点加载它们.