gpt4 book ai didi

winforms - Winform treeview 排序属性很慢

转载 作者:行者123 更新时间:2023-12-02 03:57:26 26 4
gpt4 key购买 nike

我有一个 winforms TreeView Sorted property 控制设置为真。我还通过分配 IComparer 的实例来覆盖默认排序器到 TreeViewNodeSorter属性(property)。

不幸的是,使用 AddRange 添加了几千个节点功能可能需要 10 秒。如果我设置 Sorted伪造 AddRange功能是 < 1/2 秒。 (请不要讨论添加这么多节点的有效性)

啊哈,我听到你说.. 我的 IComparer 有问题目的。不是根据探查器。几乎没有时间花在排序对象上,但 AddRange函数就在慢函数列表的顶部。

该问题很容易在测试项目中重现。只需创建一个 TreeNode 的列表s 并使用 AddRange 将其添加到现有的扩展树节点功能。这将对树文本使用默认排序 - 同样,它的速度非常慢。

为了演示如果我禁用 Sorted 会多么不成比例地慢测试项目中的属性并使用 List<T>.Sort在将它们添加到树之前在我的节点列表上添加函数(使用比较节点文本的委托(delegate))几乎没有延迟。

这导致在使用 AddRange 之前手动对节点进行排序的解决方法.没关系,但这意味着在将节点添加到现有子节点集时要找到正确的插入点需要做很多工作——比简单设置 Sorted 更不方便。为真。

有什么方法可以加速这个行为吗?

编辑 - 似乎唯一的方法是在添加之前进行排序..这有点麻烦,但我想出了以下扩展方法:

public static void AddSortedRange(this TreeNodeCollection existingNodes, IList<TreeNode>    nodes, TreeView treeView, IComparer sorter)
{
TreeNode[] array = new TreeNode[nodes.Count + existingNodes.Count];

existingNodes.CopyTo(array, 0);

nodes.CopyTo(array, existingNodes.Count);

Array.Sort(array, sorter);

treeView.BeginUpdate();

existingNodes.Clear();

existingNodes.AddRange(array);

treeView.EndUpdate();
}

将现有节点复制到数组、附加新节点、对数组排序然后替换试图在 TreeView 中内联操作节点的操作更快 - 上面代码中最慢的操作是 existingNodes.Clear()打电话

最佳答案

您遇到的性能问题与您将项目添加到已排序的 TreeView 这一事实有关。当您添加到排序列表时,在幕后发生的事情是,对于您添加的每个项目,它会尝试找到它的位置,这意味着它需要遍历整个列表 对于每个项目,现在想象一下对每个新项目进行了多少次迭代:)

你可以做的是:

TreeView tv = new TreeView(); // Just so I have a TreeView variable
TreeNode[] nodes = ... // Well, your list of nodes that you want to add
tv.SuspendLayout();
tv.Sorted = false;
tv.Nodes.Clear();
tv.Nodes.AddRange( nodes );
tv.Sorted = true;
tv.ResumeLayout();

出于性能原因,我们使用 SuspendLayout/ResumeLayout 方法来禁用 TreeView 在操作它的项目时使用的绘画过程,我们会通过删除项目来实现然后也添加它们,因为它需要重新绘制以添加您正在添加的新项目(对于每个项目)。

在我们对节点集合 进行任何更改之前,我们必须调用Sorted = false;禁用排序(这只是暂时的 - 由于 SuspendLayout,用户将看不到任何更改)。然后将项目添加到集合中(因为 TreeView 暂时没有排序,应该很快)。然后我们通过调用 Sorted = true 再次启用排序;将 Sorted 属性设置为 true 将导致集合进行排序。这样,排序只会执行一次(因此 TreeView 只会遍历项目一次)。

还有一件事,如果您为 ListView (tv.ListViewItemSorter) 定义了自定义排序器,请在添加项目之前将其设置为 null,当然这只是暂时的,在调用 ResumeLayout 之前再次启用它。

关于winforms - Winform treeview 排序属性很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11986480/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com