Windows Phone 8.1虚拟化排列布局控件

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 = 100;
        }        // 集合数量属性
        public int Count { get; set; }        // 根据索引返回数据项
        public object this[int index]
        {            get
            {                // 加载的图片是程序里面的图片资源,5张图片循环加载
                int imageIndex = 5 - index % 5;
                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

时间: 2024-10-10 18:13:11

Windows Phone 8.1虚拟化排列布局控件的相关文章

[WP8.1UI控件编程]Windows Phone VirtualizingStackPanel、ItemsStackPanel和ItemsWrapGrid虚拟化排列布局控件

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

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

原文:Windows 8.1 应用再出发 - 几种布局控件 本篇为大家介绍Windows 商店应用中几种布局控件的用法.分别是Canvas.Grid.StackPanel 和 VariableSizedWrapGrid. 1. Canvas Canvas使用绝对定位对子元素进行布局.元素使用Canvas.Left 和 Canvas.Top 附加属性进行绝对定位.元素可以使用Canvas.ZIndex附加属性指定分层,Canvas.ZIndex是int类型,值越大,分层越靠前. 所以下面代码中,如

背水一战 Windows 10 (54) - 控件(集合类): ItemsControl 的布局控件 - OrientedVirtualizingPanel, VirtualizingStackPanel, WrapGrid

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类 - ItemsControl 的布局控件) OrientedVirtualizingPanel VirtualizingStackPanel WrapGrid 示例1.OrientedVirtualizingPanel(基类) 的示例Controls/CollectionControl/ItemsControlDemo/LayoutControl/OrientedVirtualizingPanelDemo.

背水一战 Windows 10 (53) - 控件(集合类): ItemsControl 的布局控件 - ItemsStackPanel, ItemsWrapGrid

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 控件(集合类 - ItemsControl 的布局控件) ItemsStackPanel ItemsWrapGrid 示例1.ItemsStackPanel 的示例Controls/CollectionControl/ItemsControlDemo/LayoutControl/ItemsStackPanelDemo.xaml <Page x:Class="Windows10.Controls.Collection

Windows phone 8.1布局控件

布局控件(4种  第一种) Grid:相当于 HTML 中的 Table 标签,但是注意 Table 更重要的是展示数据,   而 Grid 则是专门为布局所生 属性标记: Grid.RowDefinitions:行定义,元素类型 RowDefinition,必要属性 Height Grid.ColumnDefinitions:列定义,元素类型 ColumnDefinition,必要属性 Width Width 和 Height属性单位为像素,有两个特殊值“*”.“auto” 常用附加属性: G

WPF布局控件常用属性介绍

WPF布局控件常用属性介绍 其它 | 作者:慧都控件网 | 2011-04-06 13:41:57| 阅读 0次 有用(0) 评论(0) 概述:WPF布局控件都是派生自System.Windows.Controls.Panel抽象类的面板,Panel类继承自 FrameworkElement,Panel类本身并没有什么特别的,但是WPF中提供了许多用于布局的控件都继承自Panel类,如 StackPanel控件,WrapPanel,DockPanel,Grid,UniformGrid,Canva

布局控件的概述

今日看博客园的Kevin Fan的博客,受益不少,把相关的内容精简出来,以方便 自已以后浏览. 附上kevin Fan 的博客地址:http://www.cnblogs.com/jv9/archive/2010/04/11/1709527.html. 开发windows phone 应用,免不了需要使用各种控件,kevin Fan 概括了三种类型的控件,之前自已一直没留意这方面的详细分类,看了他的分类后,作了纪录,以方便自已和他人. 界面控件,主要分为布局控件.项目控件.用户交互控件,下面主要纪

第7章(2)--布局控件常用的公共属性

分类:C#.Android.VS2015: 创建日期:2016-02-10 一.简介 Android应用程序中的布局控件都是容器控件,用于控制子元素的排列和放置方式.Android提供的布局控件有: LinearLayout:线性布局. GridLayout:网格布局. TableLayout:表布局. FrameLayout:框架布局. Relative Layout:相对布局. AbsoluteLayout:绝对布局. 二.常用的公共属性 Android的每个布局控件(layout)都是一个

WinForm界面布局控件WeifenLuo.WinFormsUI.Docking&quot;的使用 (二)

WinForm界面布局控件WeifenLuo.WinFormsUI.Docking"的使用 (二) 编写人:CC阿爸 2015-1-29 今天我想与大家继续一起分享这一伟大的控件.有兴趣的同学,可以一同探讨与学习一下,否则就略过吧. 1.    DockPanel的一点点改进: 在浏览网上的一些技术文章发现,的确有些地方还是可以进一步改进,如当双击Tab时,原先是直接把当前Tab所表示的这个窗体,从主窗体的框架上分离现来,成为一个浮动的窗体.这不是我们想要的,有些同学修改源代码,把它改成了双击关