当ListBox使用StackPanel作为容器时,如果数据源包含大量数据时,每一条数据都要创建可视化的Item来承载数据,创建这些容器就需要消耗很多时间和内存,另外滚动也非常慢,因为需要计算所有这些Item的大小和位置
如下图所示是ListBox在默认情况下加载10000个Gamer(只定义了Id和Name属性)对象时,IE的内存使用情况,此时滚动非常顺畅:
如果我们将ListBox的ItemsPanel修改为StackPanel会如何呢?下图是修改为StackPanel后IE的内存使用情况,此时滚动已经非常缓慢:
295264k 对 56372k,大概在5倍左右的差距,很显然ListBox默认使用的ItemsPanel不是StackPanel,而且可以很好的处理大量的数据加载,我们不用做任何的额外处理
对于这类问题目前有两种解决方案:
最佳的一种解决方案,其核心思想就是延迟生成每个Item,只有这些Item滚动到可视区域时才显示这些Item,在Silverlight中UI virtualization是通过VirtualizingStackPanel来实现的,VirtualizingStackPanel计算哪些Item可见,然后只为这些可见Item创建UI元素,这样实际创建的UI元素非常少,内存消耗就少,每次滚动时,也不需要计算每个Item的大小和位置,只需要计算哪些Item可见,然后为这些Item创建UI元素就可以了,滚动就非常顺畅;VirtualizingStackPanel包含两种模式:standard and recycling,standard模式就是每次Item进入可视区域都会重新创建UI元素,而recycling模式则会重用之前已经创建好的UI元素,使用该模式内存消耗更少,滚动更平滑
其核心思想是不一次性加载所有数据,只加载用户可以看到的数据,比如ListBox只加载滚到可视区域的数据,在Silverlight中实现Data virtualization主要是通过PagedCollectionView实现,PagedCollectionView提供分组、排序、过滤等许多功能,使用非常灵活、方便,其核心思想就是内部维护所有Item的集合,这个集合不会和ItemsControl进行绑定,将需要在界面中展示的那些数据包装成另外一个集合,这个集合与ItemsControl进行绑定,因为这个集合容量较小,所以实际上创建的UI元素非常少,节省内存,具体使用方法请参考MSDN,这里不再赘述
WPF中ScrollViewer提供了IsDeferredScrollingEnabled属性支持Defer Scrolling,而Silverlight没有暴露这个属性不支持DeferScrolling
http://www.silverlightshow.net/items/Virtualization-in-Silverlight-4-RC.aspx
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。