【问题标题】:Slow listView Sorting speedlistView排序速度慢
【发布时间】:2011-09-24 04:33:57
【问题描述】:

说明

我正在编写使用listView 的应用程序。我使用的listView 是一个简单的列表视图,只有我通过继承listView 打开doubleBufer 并在构造函数中写:

this->DoubleBuffer = true;

所以我的listView 中有一些列,当我单击列时,我需要对列项进行排序。当我有 500 个项目时一切正常,但是当 listView 中的项目计数超过 50.000 并且我按下列以对其中的项目进行排序时,我的列表冻结了 1 分钟并且应用程序停止响应。下面我介绍排序代码。

排序代码

ref class DomainSorter : public System::Collections::IComparer {
        public:
            virtual int Compare( System::Object^ x, System::Object^ y) {
                System::Windows::Forms::ListViewItem^ lvi1 = static_cast<System::Windows::Forms::ListViewItem^>(o1);
                System::String^ str1 = lvi1->SubItems[COLUMN_DOMAIN]->Text;
                System::Windows::Forms::ListViewItem^ lvi2 = static_cast<System::Windows::Forms::ListViewItem^>(o2);
                System::String^ str2 = lvi2->SubItems[COLUMN_DOMAIN]->Text;

                int result = 0;

                if( lvi1->ListView->Sorting == System::Windows::Forms::SortOrder::Ascending)
                     result = System::String::Compare( str1, str2 );
                else result = System::String::Compare( str2, str1 );

                return result;
            }

        };

void OnColumnClick( )
{
    listViewDomainsInfo->BeginUpdate( );
    listViewDomainsInfo->ListViewItemSorter = gcnew DomainSorter( );
    if (listViewDomainsInfo->Sorting == SortOrder::Ascending)
    listViewDomainsInfo->Sorting = SortOrder::Descending;
    else listViewDomainsInfo->Sorting = SortOrder::Ascending;
    listViewDomainsInfo->EndUpdate( ); 
}

问题

如何提高listView 排序的速度。 (我知道我可以使用虚拟列表,但我不想)你能帮我让这段代码运行得更快吗?

【问题讨论】:

  • 您正在排序 50,000 个项目。没有什么魔法能让它变得更快。您已经知道解决方案——使用虚拟模式。这种情况正是它的设计目的。但是您不想使用它,因此即使您可以对排序代码进行细微调整,也不要指望任何奇迹。
  • 非常感谢,我只是想知道是否有其他方法可以做到这一点!现在才知道没有!!你认为我必须删除这个问题吗?

标签: .net winforms sorting listview c++-cli


【解决方案1】:

如果您想要更快的排序,则不应使用集成排序行为。 例如:

  1. 重写您的排序提供程序以使用ListViewItem 而不是Object
  2. 自行排序
  3. 然后拨打listViewDomainsInfo-&gt;Items-&gt;Clear()listViewDomainsInfo-&gt;Items-&gt;AddrRange()

这应该会更快。另请注意,在这种情况下,您应该手动恢复可见项目范围。

【讨论】:

  • 为什么应该使用ListVIewItem 而不是Object 更快?它们都是引用类型;这里不涉及拳击。而且他已经用BeginUpdate/EndUpdate暂停更新,所以用AddRange清除和添加项目不太可能比他已经完成的更快。
  • 我在我的一个项目(文件管理器)中遇到了同样的问题。我已经通过这种方式解决了这个问题。现在排序 ~20000 只需不到 1 秒(请注意,我的排序更复杂)。所以我可以保证 Clear() + AddRange() 比集成 ListView 行为快得多。并且直接使用 ListViewItem 总是比将 Object 转换为 ListViewItem 更快。
【解决方案2】:

避免无响应 UI 的唯一方法是在另一个线程上对项目列表进行排序(与 ListView 分离),完成后调用 ListView.Items.ClearListView.Items.AddRange 将排序的项目添加到 @ 987654324@。不确定线程​​管理和同步的基础设施开销是否值得。

【讨论】:

    猜你喜欢
    • 2011-08-01
    • 2013-09-11
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 2021-06-06
    • 2010-10-04
    • 1970-01-01
    • 2012-01-27
    相关资源
    最近更新 更多