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. Java并发编程中的阻塞和中断

    >>线程的状态转换 线程的状态转换是线程控制的基础,下面这张图片非常直观的展示了线程的状态转换: 线程间的状态转换: 1. 新建(new):新创建了一个线程对象.2. 可运行(runnab ...

  2. ArchLinux 安装笔记:续 --zz

    续前话 在虚拟机里调试了几天,终于鼓起勇气往实体机安装了,到桌面环境为止的安装过程可以看我的前一篇文章<ArchLinux 安装笔记>.桌面环境我使用的是 GNOME,虽然用了很长一段时间 ...

  3. Analysis Services OLAP 概述2

    在DW/BI系统中,关系型数据库是存储和管理数据的最佳场所.但是关系数据库本身的智能化程度不够.关系型数据库缺乏如下功能: 丰富的元数据,帮助用户浏览数据和创建查询. 强大的分析计算和函数,在对上下文 ...

  4. [Java][Weblogic] weblogic.net.http.SOAPHttpsURLConnection incompatible with javax.net.ssl.HttpsURLConnection解决办法

    更新20141120: 我始终对修改生产上weblogic上的配置文件这一方法心存担忧(生产上的服务器不允许随便修改,可能会影响到其他应用),所以想使用代码的方式解决此问题,在对方法一失败原因进行了进 ...

  5. Linux命令之ar - 创建静态库.a文件和动态库.so

    转自:http://blog.csdn.net/eastonwoo/article/details/8241693 用途说明 创建静态库.a文件.用C/C++开发程序时经常用到,但我很少单独在命令行中 ...

  6. 【vijos】P1514天才的记忆

    描述 从前有个人名叫W and N and B,他有着天才般的记忆力,他珍藏了许多许多的宝藏.在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松回答出这个问题,便可以继承他的宝藏.题目 ...

  7. loadrunner写入数据到文件

    首先在F盘创建: F:\\LR\\test.txt文件 #define USERCOUNT 100    //定义参数数量 Action() {     char *namecommon=" ...

  8. 廖雪峰js教程笔记 2

    arguments JavaScript还有一个免费赠送的关键字arguments,它只在函数内部起作用,并且永远指向当前函数的调用者传入的所有参数.arguments类似Array但它不是一个Arr ...

  9. 个人js类库mycool

    // JavaScript Document Sunbye 1.0 //getElementById //function start var $=function(_id){return docum ...

  10. wpf中dropdownButton控件下拉居中。。。

    设置模版中popup控件的HorizontalOffset属性来控制居中. 还是对popup控件不熟,折腾了一会.