博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[WP8.1UI控件编程]Windows Phone理解和运用ItemTemplate、ContentTemplate和DataTemplate
阅读量:6805 次
发布时间:2019-06-26

本文共 5852 字,大约阅读时间需要 19 分钟。

2.2.5 ItemTemplate、ContentTemplate和DataTemplate

    在理解ItemTemplate、ContentTemplate和DataTemplate的关系的之前,我们先来看看ContentControl类和ItemsControl类。ContentControl类是内容控件的基类,如Button, CheckBox,最明显的特征就是这个控件有Content属性,有Content属性的系统控件都是ContentControl的子类。ItemsControl类是列表内容控件的基类,如ListBox,它和ContentControl类是类似的,只不过ContentControl类是单项的内容,ItemsControl是多项的内容。

    那么所有继承自ContentControl的内容控件的ContentTemplate属性和所有继承自ItemsControl的列表控件的ItemTemplate属性,都是DataTemplate类型的,意思就是我们可以通过DataTemplate来定义ContentControl和ItemsControl的控件的UI效果和数据的显示。

2.2.6 数据模板的使用

    DataTemplate是一种可视化的数据模板,它强大的作用在于可以把数据通过绑定的方式展现到控件上。在上面的例子中,我们介绍了用DataTemplate去实现了UI控件的内容的显示,那么其实DataTemplate最主要的作用并不是去取代ControlTemplate的样式定义,而是通过数据绑定把数据的控件的数据源的信息展现到控件上。

    下面我们还是通过一个Button的控件来看一下DataTemplate的数据绑定是如何发挥作用的。

    代码清单2-5数据模板(源代码:第2章\Examples_2_5)

    (1)首先定义一个Person类表示是数据实体的类型,代码如下:

public class Person    {        public string LastName { get; set; }        public string FirstName { get; set; }    }

 

    (2)设计一个DataTemplate,并把这个DataTemplate作为一个资源来使用,这是和Style资源是一样的道理,DataTemplate也可以作为公共的资源给多个控件去使用。那么这个模板的内容是使用StackPanel控件把Person对象的信息水平排列起来。

< Page.Resources>        

 

    (3)创建一个Button控件,把ContentTemplate属性和模板资源关联起来。

 

    (4)创建一个Person对象并且赋值给Button控件的Content属性。

    singlePersonButton.Content = new Person { FirstName = "lee", LastName = "Terry" };

    最后我们可以看到按钮的运行效果如图2.14所示,DataTemplate可以把数据对象绑定起来来实现更加灵活的通用的强大的UI数据显示效果。

 

     图2.14 数据模板绑定的按钮

    那么刚才的示例是DataTemplate在ContentControl类型的控件上的应用,那么下面我们再来看看DataTemplate在ItemsControl类型的控件上的实现,ContentControl和ItemsControl也是可以直接作为控件去使用的,如果我们并不需要Button或者ListBox这些控件的一些高级功能,就可以直接使用ContentControl或者ItemsControl控件。

    (1)定义一个ItemsControl控件,把ItemTemplate属性和模板资源关联起来。

<ItemsControl     x:Name="itemsControl" ItemTemplate="{StaticResource     PersonNameDataTemplate}" />

    (2)创建一个Person对象的集合并且赋值给ItemsControl控件的ItemsSource属性。

        Persons.Add(new Person { FirstName = "lee2", LastName =     "Terry2" });   

        Persons.Add(new Person { FirstName = "lee3", LastName =     "Terry3" });

        Persons.Add(new Person { FirstName = "lee4", LastName =     "Terry4" });  

        Persons.Add(new Person { FirstName = "lee5", LastName =     "Terry5" });

        itemsControl.ItemsSource = Persons;

    这时候可以看到运行效果如图2.15所示,ItemsControl可以把数据集合通过列表的形式展现出来,但是你会发现直接用ItemsControl实现的列表的功能非常有限,并且也不能滚动,接下来再结合一下ContentTemplate来进行完善这个列表的控件。

 

   图2.15 数据模板绑定的列表

    (3)定义一个ItemsControl的样式,其实就是自定义一个ControlTemplate的模板作为ItemsControl控件的模板来使用,那么这个模板就是一个内容的展现形式的模板。我们在ControlTemplate模板上定义了一个ScrollViewer控件然后里面再使用了一个StackPanel控件,最里面的是ItemsPresenter控件。列表的DataTemplate的显示内容就是直接投影在ItemsPresenter控件上面的。我们对ScrollViewer控件和StackPanel控件都设置了不同的边框颜色,这样在运行的时候就可以很明显地看出来控件之间的关系是怎样的。

 

    (4)在ItemsControl上添加Style属性为上面定义的样式。

      <ItemsControl x:Name="itemsControl"     ItemTemplate="{StaticResource PersonNameDataTemplate}"     Style="{StaticResource ItemsControlStyle}"/>

 

 

    程序的运行效果如图2.16所示。

 

图2.16 列表控件的各个模块

2.2.7 读取和更换数据模板

    对于系统的样式,我们可以通过在C#代码里面读取出来然后再修改,实现动态更换主题的目的。那么技术总是相通的,对于控件的DataTemplate,我们一样也可以通过C#代码去读取出来,然后动态地更换,实现更加丰富和灵活化的样式展示方案。在C#代码里面读取和更换数据模板也是通过对ContentTemplate属性进行读取和赋值就可以了。

    这种读取和更换数据模板在列表的控件中会比较常见,比如我要实现一个这样一个功能,通过一个列表展现出一批数据,用户打击某一条数据的时候,这条数据的样式要发生改变,表示选取了这条数据,然后用户可以取消这条数据的选择也可以继续选择多条数据。那么这样的功能在数据多选的情况下是非常普遍的功能来的。下面我们来实现这样的一个功能。

    代码清单2-6动态更换样式(源代码:第2章\Examples_2_6)

    (1)定义3个DataTemplate资源,一个是非选中状态,一个是选中状态的,还有一个是默认的状态,其实默认的状态和非选中状态是一样的,但是因为默认的状态的数据项样式不能在C#里面再次调用。在两个模板中都添加了Tap事件,用户捕获用户的点击事件。数据源集合与上一个例子一样。

< Page.Resources>        
……省略若干代码 //创建ItemsControl控件来绑定列表的数据

 

    (2)处理点击事件,判断当前控件的模板和重新赋值模板。可以通过Name属性访问XAML中定义的DataTemplate。

private void StackPanel_Tap_1(object sender, TappedRoutedEventArgs e)    {        // 获取ItemsControl对象的ItemContainerGenerator属性        // 通过点击的控件的DataContext判断所绑定的数据对象        // 然后从ItemContainerGenerator里面获取到当前的ContentPresenter对象        ContentPresenter myContentPresenter = (ContentPresenter)(listbox.ItemContainerGenerator.ContainerFromItem((sender as Panel).DataContext));        // 判断数据模板是选中状态的还是非选中状态的,然后进行赋值        if (myContentPresenter.ContentTemplate.Equals(dataTemplateSelectName))        {            //赋值非选中状态的模板            myContentPresenter.ContentTemplate = dataTemplateNoSelectName;        }        else        {            //赋值选中状态的模板            myContentPresenter.ContentTemplate = dataTemplateSelectName;        }    }

 

    运行的效果如图2.17所示,当我们点击一下数据项的时候,字体会变大,背景会变成红色,在点击一次就会变成原来的样子。

 

图2.17 动态更换样式

    (3)在这里还要注意一点的是,如果使用的时ListBox控件而不是ItemsControl控件的时候,在获取ContentPresenter对象的时候需要通过可视化树去查找。代码的实现如下所示:

private void StackPanel_Tap_1(object sender, TappedRoutedEventArgs e)    {         //获取到的对象是ListBoxItem         ListBoxItem myListBoxItem =  (ListBoxItem)(listbox.ItemContainerGenerator.ContainerFromItem((sender as Panel).DataContext));         // 在ListBoxItem中查找ContentPresenter         ContentPresenter myContentPresenter = FindVisualChild
(myListBoxItem); ……//省略若干代码 } //查找可视化树某个类型的元素 private childItem FindVisualChild
(DependencyObject obj) where childItem : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { DependencyObject child = VisualTreeHelper.GetChild(obj, i); if (child != null && child is childItem) return (childItem)child; else { childItem childOfChild = FindVisualChild
(child); if (childOfChild != null) return childOfChild; } } return null; }

本文来源于

源代码下载:

欢迎关注我的微博

WP8.1技术交流群:372552293

转载地址:http://ygjwl.baihongyu.com/

你可能感兴趣的文章
数据结构之线性表
查看>>
在PPT中插入FLASH遇到的系列问题
查看>>
XSS研究4-来自外部的XSS攻击的防范
查看>>
Spring知识点总结-1
查看>>
微软私有云分享(R2)21 BMC提升B格
查看>>
MDSF:如何使用GMF来做TOGAF建模工具
查看>>
Spring Security简介
查看>>
打造一流的研发中心
查看>>
MCollective架构篇3-Puppet插件的部署及测试
查看>>
配置GNS使用CRT连接
查看>>
Java:集合类性能分析
查看>>
cms无法登陆
查看>>
JavaScript中事件处理
查看>>
VSTO 向office文档中插入内容
查看>>
【百度地图API】关于如何进行城市切换的三种方式
查看>>
How to provide highlighting with Spring data elasticsearch
查看>>
MongoDB 游标
查看>>
即将搭载人工智能芯片的华为Mate10,究竟会为业界带来什么?
查看>>
Android实现登录小demo
查看>>
AgentWeb是基于Android WebView一个功能完善小型浏览器库
查看>>