问题描述
|
我相信你们大多数人现在都会感到惊讶,为什么我们必须为wpf数据网格关闭虚拟化。尽管虚拟化确实有助于减少内存占用,但它增加了cpu开销,并且滚动体验并非完美无缺。
由于客户的要求,我们不得不禁用数据网格中的虚拟化并对其进行进一步优化,现在它可以非常平滑地上下滚动而没有任何滞后。缺点是数据已预加载并保存在内存中。这是我们可以接受的解决方案。
但是,分类现在已经成为一个大问题。虽然确实可以使用CustomSorter:IComparer代替常规的SortDecriptors进行更好的排序,但在整个情况下,尽管重新绘制了整行,这几乎没有任何区别。
有什么方法可以提高非虚拟化数据网格上的排序速度?
高度赞赏,
更新:
我遇到了一个想法,我正在尝试实施。解除对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;
}
}
这将利用优于SortDescriptor的更快的比较器排序。
现在的问题是,我在哪个阶段取消绑定项目排序,应用排序,等待排序,一旦事件(哪个事件)触发,然后将Itemssource重新绑定到视图。
BindingOperations.ClearBinding(this,ItemsSourceProperty);
上面的这一行将清除绑定。
//apply the sort
lcv.CustomSort = comparer;
从理论上讲(不确定这是否正确)ItemsSource = lcv;会重新绑定它。但是性能还是一样的。 :(
有人知道吗?
解决方法
我猜这里的性能问题不是排序,而是绑定和重新绑定本身。
只需清除绑定,然后重新绑定网格即可。与排序相比,您应该不会看到太大的差异。
如果是这种情况,则可以尝试简化该网格的模板和样式(如果使用的话)。
,尝试先对集合进行排序,然后将排序后的集合绑定到DataGrid。排序操作的速度取决于您将使用的排序算法。我曾经使用插入排序算法,您可以在http://en.wikipedia.org/wiki/Insertion_sort中了解该算法。我将尽快给您发送示例。
更新资料
您可以在此处找到
VB.Net
实现
您可以在此处找到C#
实现