我相信你们中的大多数人现在会对为什么我们必须关闭 wpf 数据网格的虚拟化感到惊讶。虽然虚拟化确实有助于减少内存占用,但它增加了 CPU 开销并且滚动体验并非完美无缺。
根据客户的要求,我们不得不禁用数据网格中的虚拟化并进一步优化它,现在它可以非常顺畅地上下滚动,没有任何延迟。缺点是数据被预加载并保存在内存中。这是我们可以接受的解决方案。
然而排序现在成了一个大问题。虽然使用 CustomSorter : IComparer 确实是比通常的 SortDecriptors 更好的排序替代方案,但它在我们的案例中几乎没有任何区别,因为整行都被重绘了。
有什么方法可以提高非虚拟化数据网格的排序速度吗?
非常感谢,
更新:
我有一个想法,我正在努力实现。解绑 Itemssource,进行排序,排序完成后,重新绑定(bind) 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;
}
}
这将利用比 SortDescriptors 更快的比较器排序。 现在的问题是我在什么阶段取消绑定(bind)项目排序、应用排序、等待排序,一旦事件(哪一个?)触发然后将 Itemssource 重新绑定(bind)到 View 。
BindingOperations.ClearBinding(this, ItemsSourceProperty);
上面的这一行将清除绑定(bind)。
//apply the sort
lcv.CustomSort = comparer;
理论上(不确定这是否正确) ItemsSource = lcv;会重新绑定(bind)它。但是性能还是一样的。 :(
有人知道吗?
最佳答案
我想这里的性能问题不是排序而是绑定(bind)和重新绑定(bind)本身。
只需清除绑定(bind)并重新绑定(bind)您的网格。与排序相比,您应该看不出太大的区别。
如果是这种情况,您可以尝试简化该网格的模板和样式(如果您正在使用)。
关于c# - 如何提高非虚拟化 DataGrid 的排序性能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6123336/