11.2.2 VirtualizingStackPanel、ItemsStackPanel和ItemsWrapGrid虚拟化排列布局控件

VirtualizingStackPanel、ItemsStackPanel和ItemsWrapGrid都是虚拟化布局控件,一般情况下在界面的布局上很少会用到这些虚拟化排列的控件,大部分都是封装在列表的布局面板上使用,主要的目的就是为了实现列表上大数据量的虚拟化,从而极大地提高列表的效率。那么其实这3个虚拟化布局控件都是列表控件的默认布局排列的方式,其中VirtualizingStackPanel控件是ListBox的默认布局面板,ItemsStackPanel是ListView的默认布局面板,ItemsWrapGrid是GridView的默认布局面板。

VirtualizingStackPanel控件和ItemsStackPanel控件都是表示沿着水平方向或垂直垂直方向将内容虚拟化地排列在一行上。它们控件所实现的排列布局效果和StackPanel控件是一样的,不同的是这些控件可以实现虚拟化的逻辑。对于数据较多的列表布局,使用VirtualizingStackPanel控件或者ItemsStackPanel控件会比StackPanel控件高效很多,因为虚拟化控件只是把当前屏幕范围内的数据显示出来,其他的数据都通过虚拟化的技术进行处理,并没有进行UI的初始化显示,所以效率很高。ItemsWrapGrid控件实现的则是网格的虚拟化布局效果,虚拟化原理也是和ItemsStackPanel控件类似的,只不过他们排列的方式不一样。

这些虚拟化排列布局控件会计算可见项的数量,并处理来自 ItemsControl(如 ListBox)的ItemContainerGenerator,以便只为可见项创建 UI 元素。仅当StackPanel中包含的项控件创建自己的项容器时,才会在该面板中发生虚拟化。 可以使用数据绑定来确保发生这一过程,如果是直接创建列表的项元素然后添加为虚拟化排列布局控件的子对象,那么这种方式是不会进行虚拟化处理的。下面以ItemsStackPanel来说明我们如何去利用虚拟化排列布局控件去解决一些实际的问题。

ItemsStackPanel是ListView元素的默认项宿主。使用ListView列表控件绑定数据的时候,默认是采用了ItemsStackPanel控件对数据项进行排列。如果你使用ItemsControl列表控件来展示数据,要给这个列表增加虚拟化的功能,ItemsStackPanel对象元素必须包含在一个ItemsPanelTemplate中。现在我们再回过头来看本章的第一个例子,用ItemsControl控件绑定到2000个数据项的集合的时候,加载的速度很慢,这就是没有使用虚拟化的结果。如果在ItemsControl控件上使用ItemsStackPanel来进行虚拟化布局,那么你会发现加载的速度非常快。给ItemsControl控件添加ItemsStackPanel虚拟化布局,需要把代码修改成如下:

    <ItemsControl x:Name="itemsControl">
<!--使用ItemsStackPanel控件作为ItemsControl的布局面板-->
< ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel/>
</ItemsPanelTemplate>
</ ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
……省略若干代码
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

如果在列表中需要使用到ItemsStackPanel控件虚拟化的技术的时候,还要注意一个事情是,不要破坏ScrollViewer和ItemsPresenter的结构,否则将实现不了虚拟化的效果。如果你在ScrollViewer和ItemsPresenter之间再添加一个StackPanel控件,如下所示:

    <ControlTemplate TargetType="ItemsControl">
<ScrollViewer>
<StackPanel>
<ItemsPresenter/>
</StackPanel>
</ScrollViewer>
</ControlTemplate>

那么这时候,ItemsStackPanel控件会一次性把所有的数据都初始化,不会起到虚拟化的作用。因为ItemsStackPanel控件虚拟化的时候是根据每个Item的固定的大小来进行布局的虚拟化处理的,当在ScrollViewer和ItemsPresenter中加入了其他的控件之后会破坏了ItemsStackPanel控件的虚拟化布局,导致ItemsStackPanel控件无法准确地测量出来列表的数据项的布局。

11.2.3 实现横向虚拟化布局

通常我们实现的列表布局大部分都是竖向的布局,包括GridView控件的布局整体上也是竖向的布局。那么ListView控件和ListBox控件默认都是竖向垂直滚动的列表,如果要让其水平滚动那么就需要自定义其布局的面板,这时候我们就可以使用ItemsStackPanel控件去实现了,如果我们并不需要ListView控件的那么多的功能和效果,就可以直接使用最基本的列表控件ItemsControl控件搭配ItemsStackPanel控件去实现横向滚动的效果,并且带有虚拟化的功能。

下面我们用一个例子使用ItemsControl控件横向滚动展示图片,在这个例子里面会使用到ItemsStackPanel控件的Horizontal布局。列表中会有100个数据项,我们通过日志来查看其加载的数据项是怎样的。

代码清单11-7横向虚拟化列表(源代码:第11章\Examples_11_7)

(1)首先,创建实体类和自定义的集合类,实体类Item和自定义的集合类ItemList。

Item.cs文件主要代码
------------------------------------------------------------------------------------------------------------------
public class Item
{
// 图片对象
public BitmapImage Image { get; set; }
// 图片名字
public string ImageName { get; set; }
}
ItemList.cs文件主要代码
------------------------------------------------------------------------------------------------------------------
public class ItemList : IList
{
// 设置集合的数量为100
public ItemList()
{
Count = ;
}
// 集合数量属性
public int Count { get; set; }
// 根据索引返回数据项
public object this[int index]
{
get
{
// 加载的图片是程序里面的图片资源,5张图片循环加载
int imageIndex = - index % ;
Debug.WriteLine("加载的集合索引是:" + index );
return new Item { ImageName = "图片" + index, Image = new BitmapImage(new Uri("ms-appx:///Images/" + imageIndex + ".jpg", UriKind.RelativeOrAbsolute)) };
}
set
{
throw new NotImplementedException();
}
}
//……省略若干代码
}

(2)实现ItemsControl的横向虚拟化布局。

要实现ItemsControl的横向虚拟化布局,除了使用ItemsStackPanel控件的Horizontal布局,还需要在ItemsControl中设置ScrollViewer.HorizontalScrollBarVisibility="Auto",这样列表就可以水平滚动了。列表的代码如下:

MainPage.xaml文件主要代码
------------------------------------------------------------------------------------------------------------------
<ItemsControl x:Name="list">
<!--使用ItemsStackPanel控件作为ItemsControl的布局面板-->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility ="Disabled">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<Image Source="{Binding Image}" Width="144" Height="240" Stretch="UniformToFill"></Image>
<TextBlock Text="{Binding ImageName}"></TextBlock>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
MainPage.xaml.cs文件主要代码
------------------------------------------------------------------------------------------------------------------
public MainPage()
{
InitializeComponent();
list.ItemsSource = new ItemList();
}

(3)列表的运行效果如图11.8所示,采用Debug调试下运行程序可以看到日志显示列表只是初始化了10个数据项,日志如下所示:

/*日志开始*/

加载的集合索引是:0

加载的集合索引是:1

加载的集合索引是:2

加载的集合索引是:3

加载的集合索引是:4

加载的集合索引是:5

加载的集合索引是:6

加载的集合索引是:7

加载的集合索引是:8

加载的集合索引是:9

/*日志开始*/

本文来源于《深入理解Windows Phone 8.1 UI控件编程》

源代码下载:http://vdisk.weibo.com/s/zt_pyrfNHoezI

欢迎关注我的微博@WP林政

WP8.1技术交流群:372552293

[WP8.1UI控件编程]Windows Phone VirtualizingStackPanel、ItemsStackPanel和ItemsWrapGrid虚拟化排列布局控件的更多相关文章

  1. [WP8.1UI控件编程]Windows Phone XAML页面的编译

    1.1.2 XAML页面的编译 Windows Phone的应用程序项目会通过Visual Studio完成XAML页面的编译,在程序运行时会通过直接链接操作加载和解析XAML,将XAML和过程式代码 ...

  2. [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化

    11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...

  3. [WP8.1UI控件编程]Windows Phone动画方案的选择

    8.1 动画方案的选择 Windows Phone的动画实现方式有线性插值动画(3种类型).关键祯动画(4种类型)和基于帧动画,甚至还有定时器动画,然后动画所改变的UI元素属性可以是普通的UI元素属性 ...

  4. [WP8.1UI控件编程]Windows Phone理解和运用ItemTemplate、ContentTemplate和DataTemplate

    2.2.5 ItemTemplate.ContentTemplate和DataTemplate 在理解ItemTemplate.ContentTemplate和DataTemplate的关系的之前,我 ...

  5. [WP8.1UI控件编程]Windows Phone自定义布局规则

    3.2 自定义布局规则 上一节介绍了Windows Phone的系统布局面板和布局系统的相关原理,那么系统的布局面板并不一定会满足所有的你想要实现的布局规律,如果有一些特殊的布局规律,系统的布局面板是 ...

  6. Windows 8.1 应用再出发 - 几种布局控件

    本篇为大家介绍Windows 商店应用中几种布局控件的用法.分别是Canvas.Grid.StackPanel 和 VariableSizedWrapGrid. 1. Canvas Canvas使用绝 ...

  7. 《深入理解Windows Phone 8.1 UI控件编程》基于最新的Runtime框架

    <深入理解Windows Phone 8.1 UI控件编程>本书基于最新的Windows Phone 8.1 Runtime SDK编写,全面深入地论述了最酷的UI编程技术:实现复杂炫酷的 ...

  8. Expression Blend实例中文教程(5) - 布局控件快速入门StackPanel,ScrollViewer和Border

    上一篇,介绍了Canvas布局控件在Blend中的使用.本篇继续介绍布局控件StackPanel,ScrollViewer和Border. 相对于Grid和Canvas来说,StackPanel,Sc ...

  9. Expression Blend实例中文教程(4) - 布局控件快速入门Canvas

    上一篇,我介绍了Silverlight控件被分为三种类型, 第一类: Layout Controls(布局控件) 第二类: Item Controls (项目控件) 第三类: User Interac ...

随机推荐

  1. DOM – 4.doucument属性

    4.document属性 2.1 write 2.2 getElementById 方法 getElementsByName getElementsByTagName 案例:全选反选 案例:点击一个按 ...

  2. Java Eclipse进行断点调试

    如何调试Java程序? 大家最开始学习Java,都会觉得IDE调试好高端有木有,其实很简单了. 下文会尽量简单直观的教会你在Eclipse中调试,其他的IDE调试步骤也是类似的. 1.在你觉得有错的地 ...

  3. 【翻译八】java-内存一致性错误

    Memory Consistency Errors Memory consistency errors occur when different threads have inconsistent v ...

  4. python装饰器入门

    按别人的教程弄的. 要清楚基于类和基于函数的实现的不同之处. #!/usr/bin/env python # -*- coding: utf-8 -*- ''' class entryExit(obj ...

  5. HDU5558 Alice's Classified Message(合肥区域赛 后缀数组)

    当初合肥区域赛的题(现场赛改了数据范围就暴力过了),可惜当初后缀数组算法的名字都没听过,现在重做下. i从1到n - 1,每次枚举rank[i]附近的排名,并记录当起点小于i时的LCP(rank[i] ...

  6. hdu 4756 MST+树形dp ****

    题意:给你n(n = 1000)个二维点,第一个点是power plant,还有n - 1个点是dormitories.然后现在知道有一条寝室到寝室的边是不能连的,但是我们不知道是哪条边,问这种情况下 ...

  7. hdu 4738 2013杭州赛区网络赛 桥+重边+连通判断 ***

    题意:有n座岛和m条桥,每条桥上有w个兵守着,现在要派不少于守桥的士兵数的人去炸桥,只能炸一条桥,使得这n座岛不连通,求最少要派多少人去. 处理重边 边在遍历的时候,第一个返回的一定是之前去的边,所以 ...

  8. [Outlook] outlook如何实现自动CC和BCC邮件发送

    由于需要在不同机器上发送邮件,最终发送的邮件会在不同的机器上,最终导致邮件丢失,以后想找也找不回来,故在网上搜索一翻,找到解决办法. 1. 实现自动CC邮件发送: 方法:使用outlook的配置规则 ...

  9. POJ 1840 Eqs 二分+map/hash

    Description Consider equations having the following form: a1x13+ a2x23+ a3x33+ a4x43+ a5x53=0 The co ...

  10. bat 炸弹升级

    转自:http://digi.163.com/15/0320/06/AL4LP0QD0016192R.html 第1页:什么是批处理炸弹? 最近网上流传一个叫做<大哥别杀我>视频纷纷遭到网 ...