如何在无虚拟化数据网格上提高排序性能

本文关键字:高排序 排序 性能 网格 虚拟化 数据网 数据 | 更新日期: 2023-09-27 17:57:42

我相信你们大多数人现在都会惊讶于为什么我们必须关闭wpf数据网格的虚拟化。虽然虚拟化确实有助于减少内存占用,但它会增加CPU开销,滚动体验也并非完美无瑕。

由于客户的要求,我们不得不禁用数据网格中的虚拟化并对其进行进一步优化,现在它可以非常平稳地上下滚动,没有任何延迟。缺点是数据被预先加载并保存在内存中。这是一个我们可以接受的解决方案。

然而,排序现在已经成为一个大问题。虽然使用CustomSorter:IComparer确实是比通常的SortDecriptor更好的排序替代方案,但在我们的情况下,它几乎没有任何区别,因为整行都在重新绘制。

有什么方法可以提高非虚拟化数据网格上的排序速度吗?

高度赞赏,

更新:

我遇到了一个想法,我正在努力实现它。取消绑定项目源,进行排序,排序完成后,重新绑定项目源。

为了实现这一点,我从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;
        }
    }

这将利用比SortDescriptors更快的Comparer排序。现在的问题是,在哪个阶段,我应该解除项目排序的绑定,应用排序,等待排序,一旦事件(哪一个?)触发,然后将Itemssource重新绑定到视图。

BindingOperations.ClearBinding(this, ItemsSourceProperty);

上面的这一行将清除绑定。

//apply the sort
            lcv.CustomSort = comparer;

理论上(不确定这是否是正确的方式)ItemsSource=lcv;会重新绑定。但性能仍然不变。:(

有人知道吗?

如何在无虚拟化数据网格上提高排序性能

我想这里的性能问题不是排序,而是绑定和重新绑定本身。

只需清除绑定并重新绑定网格即可。与排序相比,您不应该看到太大的差异。

如果是这种情况,您可以尝试简化该网格的模板和样式,如果您正在使用任何模板和样式的话。

尝试先对集合进行排序,然后将排序后的集合绑定到DataGrid。排序操作的速度取决于您将使用的排序算法。我曾经使用插入排序算法您可以在http://en.wikipedia.org/wiki/Insertion_sort。我很快就会给你发一个例子。

更新

你可以在这里找到VB.Net实现

您可以在此处找到C#实现