为了实现一个可以快速加载大量数据的datagrid ,经过长时间的查询之后,总结如下
1 datagrid 需要开启虚拟化:
VirtualizingPanel.IsContainerVirtualizable="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsContainerVirtualizable="True" 指是否开启虚拟化
VirtualizingPanel.VirtualizationMode="Recycling" 指不循环实例化新的Item
虚拟化开启之后,会在实际显示对象时才加载对象
2 ItemSource的赋值方式
2.1 使用IList 构建虚拟数据源。
因为IList是使用时才加载对象,所以在知道总数的前提下,可以直接构建一批数据源。如:
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < Count; i++)
{
yield return this[i];
}
}
将IEnumerator作为数据源绑定到ItemSource上。当使用某个对象时,才会根据index实际查询该对象。
优点:只需要知道数据源总数及模型即可构建,加载速度快。同时datagrid 的滚动条也是根据总数来计算的,所以不用考虑滚动条的长度等问题
缺点:数据源是同步加载的,不能异步加载,如果频繁操作的话,可能会导致卡顿。
参考例子:
2.2 设置一个最大显示的条数,如五千。当数据源为空时,构建一个ObservationCollection作为数据源。当外界条件变化导致数据源变化时,对比最新的数据源条数与当前的数据源条数。最大为五千,如不足最新数据源,则补齐条数;如大于最新数据源,则移除对应的条数。然后把最新数据源的对象经过深拷贝替换进入当前数据源对象。相当于使用一个五千条数据的控件占位,然后不停的替换里面的内容。
优点:可以异步加载数据,频繁操作时,可以使用队列等方式只加载最后一次所需要的数据
缺点:需要自己监控滚动条的滚动事件,鼠标滚轮事件来计算当前滚动的距离,根据当前滚动的距离计算出对应需要显示的内容。如果计算的不好,那么数据刷新可能会有问题