Viktor Apoyan
Viktor Apoyan

Reputation: 10755

Slow listView Sorting speed

Description

I'm writing application what use listView. listView that I use is a simple list view, only I switch on doubleBufer by inheriting listView and in constructor I have write:

this->DoubleBuffer = true;

So I have some columns in my listView and when I click column I need to sort column items. Everything goes okay when I have 500 items, but when items count in listView become more then 50.000 and I press column in order to sort items in it, my list froze for 1 minute and application stop response. Below I present code of sorting.

Sorting Code

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

Question

How I can increase speed of listView sorting. (I knew that I can use virtual list but I didn't want) can you help me to make this code works faster ?

Upvotes: 1

Views: 1198

Answers (2)

Florian Greinacher
Florian Greinacher

Reputation: 14784

The only thing you could do to avoid the unresponsive UI is to sort the items list on another thread (decoupled from the ListView) and when done call ListView.Items.Clear and ListView.Items.AddRange to add the sorted items to the ListView. Not sure if the infrastructural overhead of thread management and synchronization are worth the effort.

Upvotes: 0

treetey
treetey

Reputation: 829

If you want the faster sorting you should not to use integrated sorting behavior. For example:

  1. Rewrite your sorting provider to work with ListViewItem instead Object
  2. Sort items by yourself
  3. Then call listViewDomainsInfo->Items->Clear() and listViewDomainsInfo->Items->AddrRange()

That's should work faster. Also note that you should restore visible items range manually in this case.

Upvotes: 1

Related Questions