Как улучшить производительность сортировки на нет-виртуализированном DataGrid?

Я уверен, что большинство из вас теперь будут удивлены, почему нам пришлось отключить виртуализацию для wpf datagrid. Несмотря на то, что виртуализация помогает уменьшить объем памяти, она добавляет накладные расходы процессора, а опыт прокрутки не является безупречным.

Из-за нашего клиентского запроса нам пришлось отключить виртуализацию в datagrid и оптимизировать ее дальше, и теперь она прокручивается очень плавно вверх и вниз без какого-либо отставания. Недостатком является то, что данные предварительно загружаются и сохраняются в памяти. Это решение, с которым мы можем жить.

Однако сортировка стала большой проблемой. Хотя верно, что использование CustomSorter: IComparer будет лучшей альтернативой сортировки для обычных SortDecriptors, это едва ли имеет значение в нашем случае, хотя, поскольку все строки перерисовываются.

Есть ли способ улучшить скорость сортировки на не виртуализированном datagrid?

Высоко ценится,

UPDATE:

Я столкнулся с идеей, которую я пытаюсь реализовать. Отвязывая Itemssource, выполните сортировку, и как только сортировка закончится, переустановите Itemssource.

Чтобы достичь этого, я получаю от DataGrid для захвата SortHandler (то есть, когда пользователь щелкает по столбцу)

public class CustomSortDataGrid : DataGrid
    {
        public CustomSortDataGrid()
        {
            Sorting += SortHandler;
        }

        private void SortHandler(object sender, DataGridSortingEventArgs e)
        {
            DataGridColumn column = e.Column;
            IComparer comparer = null;

            // prevent the built-in sort from sorting
            e.Handled = true;

            ListSortDirection direction = (column.SortDirection != ListSortDirection.Ascending) ? ListSortDirection.Ascending : ListSortDirection.Descending;

            //set the sort order on the column
            column.SortDirection = direction;

            //use a ListCollectionView to do the sort.
            var lcv = (ListCollectionView)CollectionViewSource.GetDefaultView(ItemsSource);


            comparer = new BidYieldComparer(direction);

            //apply the sort
            lcv.CustomSort = comparer;

        }
    }

Это будет использовать более быструю сортировку Comparer, превосходящую SortDescriptors. Теперь вопрос заключается в том, на каком этапе я отвязываю сортировку элементов, применяю сортировку, дожидаюсь сортировки, как только событие (которое??) Срабатывает, а затем повторно привязывает Itemssource к представлению.

BindingOperations.ClearBinding(this, ItemsSourceProperty);

Эта строка выше очистит привязку.

//apply the sort
            lcv.CustomSort = comparer;

И теоретически (неуверенный, если это правильный путь) ItemsSource = lcv; повторит его. Но производительность все тот же.: (

Любая идея кого-нибудь?

Ответ 1

Попробуйте сначала отсортировать свою коллекцию, а затем привяжите отсортированную коллекцию к вашему DataGrid. Скорость сортировки зависит от алгоритма сортировки, который вы будете использовать. Я использовал алгоритм сортировки вставки, который вы можете прочитать об этом алгоритме в http://en.wikipedia.org/wiki/Insertion_sort. Я пришлю вам пример в ближайшее время.

Обновление

вы можете найти реализацию VB.Net здесь

вы можете найти реализацию C# здесь

Ответ 2

Я предполагаю, что проблема с производительностью здесь не в сортировке, а в привязке и повторной привязке.

Просто очистите привязку и перевяжите свою сетку. Вы не должны видеть большую разницу по сравнению с сортировкой.

Если это так, вы можете попытаться упростить свои шаблоны и стили для этой сетки, если вы используете их.