Как улучшить производительность сортировки на нет-виртуализированном 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
Я предполагаю, что проблема с производительностью здесь не в сортировке, а в привязке и повторной привязке.
Просто очистите привязку и перевяжите свою сетку. Вы не должны видеть большую разницу по сравнению с сортировкой.
Если это так, вы можете попытаться упростить свои шаблоны и стили для этой сетки, если вы используете их.