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. MVC – 8.Razor 布局

    8.1.@RenderBody() 8.2.多个"占位符":@RenderSection() 8.3.js合并 @Scripts.Render("~/bundles/js ...

  2. 菜鸟学Linux命令:端口查看和操作命令

    >>端口和进程 端口不是独立存在的,它是依附于进程的.某个进程开启,那么它对应的端口就开启了,进程关闭,则该端口也就关闭了.下次若某个进程再次开启,则相应的端口也再次开启. >> ...

  3. HTML5学习之跨文档传输消息(七)

    新标准中提供了文档之间直接的消息传输API.而且不限制跨域消息传递! 发送消息使用的是Window对象的postMessage(data,targetURL)方法就可以了,但给哪个window对象发送 ...

  4. 使用JDBC的addBatch()方法提高效率

    在批量更新SQL操作的时候建议使用addBatch,这样效率是高些,数据量越大越能体现出来 Statement接口里有两个方法:void     addBatch(String sql)将给定的 SQ ...

  5. 10g 11g配置Logical Standby

    1.创建一个物理Standby数据库 详细见11g Physical Standby配置 2.Standby数据库取消managed  recovery ALTER DATABASE RECOVER ...

  6. maven 依赖查询

    该文章源地址:http://xiejianglei163.blog.163.com/blog/static/1247276201362733217604/ 为方便个人使用,转载于此处. http:// ...

  7. ortp库入门

    转自:http://blog.csdn.net/suer0101/article/details/7333267 再补充一个代码走读:http://www.xuebuyuan.com/1863409. ...

  8. SQLite密码添加移除

    背景:电脑清理--个人洁癖 SQLite的最原始的是没有加密的,从而衍生了多种加密算法,但在平常使用中使用System.Data.Sqlite,但其加密后,一般都需要要单独的sqlite管理器--像我 ...

  9. ios录音

    #import "ViewController.h" #import <AVFoundation/AVFoundation.h> @interface ViewCont ...

  10. 及其简短的Splay代码

    #include <stdio.h> #include <queue> #include <algorithm> #include <stdlib.h> ...