实现Windows Phone7 的DataTemplateSelector和CustomDataTemplateSelector

文章介绍了如何在WindowsPhone7开发环境中创建DataTemplateSelector的虚类和自定义CustomDataTemplateSelector,重点阐述了DataTemplateSelector如何根据数据对象和数据绑定选择合适的DataTemplate。通过实现一个FoodTemplateSelector作为示例,展示了如何根据不同类型的元素选择不同样式呈现,最终实现在ListBox中动态应用多种模板的效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:http://blog.youkuaiyun.com/huangliangjie/article/details/6690086  

在这篇文章中,我将要介绍在Windows Phone 7开发环境中怎么去创建一个DataTemplateSelector的虚类和自定义一个CustomDataTemplateSelector。通常DataTemplateSelector提供一种基于数据对象和数据绑定的选择DataTemplate的途径。特别是在对于同类的对象有多个DataTemplate,并且能根据逻辑选择DataTemplate应用到数据对象上。

        简单的说,DataTemplateSelector允许我们编写一些逻辑去选择哪个DataTemplate运用到哪个特定的项上。甚至可以创建一个新的Template 。

         

NOTE: DataTemplateSelector 在WPF中是一个很好用的类,不过它现在还没有Silverlight版本

下面是一个在dev forums很热门的一个问题

"I have a list of different types of elements. I would like to display a different data template for different list elements, based on what type it is. "

这个问题的答案是利用DataTemplateSelector。因此在这篇文章里我先要解释怎么去实现一个DataTemplateSelector,然后我会介绍怎么去实现自己的自定义CustomDataTemplateSelector 。最后的效果图会贴在本文中。

 

 实现DataTemplateSelector虚类



有很多的方法去建立一个动态的DataTemplateSelector 。你可以从WPF默认实现DataTemplateSelector的代码中去提取代码,利用ValueConverter实现等等。在这篇文章中我会介绍怎么去建立一个继承自ContentControl(这里把ContentControl当做一个基类) 的DataTemplateSelector 。


我们要做的第一件事就是建立一个带有选择合适Template虚方法抽象类。这个虚方法SelectTemplate可以根据优先属性的值(在一个继承自DataTemplateSelector特定的类被重写时)返回一个合适的Template。这里需要重写基类的OnContentChanhed 事件,下面是源码:

[csharp] view plain copy print ?
  1. public abstract class DataTemplateSelector : ContentControl  
  2. {  
  3.     public virtual DataTemplate SelectTemplate(object item, DependencyObject container)  
  4.     {  
  5.         return null;  
  6.     }  
  7.   
  8.     protected override void OnContentChanged(object oldContent, object newContent)  
  9.     {  
  10.         base.OnContentChanged(oldContent, newContent);  
  11.   
  12.         ContentTemplate = SelectTemplate(newContent, this);  
  13.     }  
  14. }  



建立一个自定义的CustomDataTemplateSelector


为了建立一个自定义的模板选择器,首先需要建立一个继承自DataTemplateSelector 的类,然后要override它的SelectTemplate方法。一旦你的类定义好之后,你就可以把这个类的实例指定给你的界面element的template selector property。


为了演示,这里我会建立一个FoodTemplateSelector 类,它包含三个不同的DataTemplates:Healthy, UnHealthy and NotDetermined。在SelectTemplate 方法里我会加上一些条件,这些条件可以根据 data context的属性值选择合适的DataTemplate。基本上我们可以通过数据源的属性值选择正确的template。


这个FoodTemplateSelector 的源码如下:


 
[csharp] view plain copy print ?
  1. public class FoodTemplateSelector : DataTemplateSelector  
  2. {  
  3.     public DataTemplate Healthy  
  4.     {  
  5.         get;  
  6.         set;  
  7.     }  
  8.   
  9.     public DataTemplate UnHealthy  
  10.     {  
  11.         get;  
  12.         set;  
  13.     }  
  14.   
  15.     public DataTemplate NotDetermined  
  16.     {  
  17.         get;  
  18.         set;  
  19.     }  
  20.   
  21.     public override DataTemplate SelectTemplate(object item, DependencyObject container)  
  22.     {  
  23.         Data foodItem = item as Data;  
  24.         if (foodItem != null)  
  25.         {  
  26.             if (foodItem.Type == "Healthy")  
  27.             {  
  28.                 return Healthy;  
  29.             }  
  30.             else if (foodItem.Type == "NotDetermined")  
  31.             {  
  32.                 return NotDetermined;  
  33.             }  
  34.             else  
  35.             {  
  36.                 return UnHealthy;  
  37.             }  
  38.         }  
  39.   
  40.         return base.SelectTemplate(item, container);  
  41.     }  
  42. }  

这里是数据类:


 
[csharp] view plain copy print ?
  1. public class Data  
  2. {  
  3.     public string Name  
  4.     {  
  5.         get;  
  6.         set;  
  7.     }  
  8.   
  9.     public string Description  
  10.     {  
  11.         get;  
  12.         set;  
  13.     }  
  14.   
  15.     public string IconUri  
  16.     {  
  17.         get;  
  18.         set;  
  19.     }  
  20.   
  21.     public string Type  
  22.     {  
  23.         get;  
  24.         set;  
  25.     }  
  26. }  

 

这里为了表明FoodTemplateSelector的用法,使用了一个数据绑定的ListBox。这里是绑定的源码:


 
[csharp] view plain copy print ?
  1. public MainPage()  
  2.         {  
  3.             InitializeComponent();  
  4.   
  5.             List<Data> list = new List<Data>();  
  6.             Data item0 = new Data() { Name = "Tomato", IconUri = "Images/Tomato.png", Type = "Healthy" };  
  7.             Data item1 = new Data() { Name = "Beer", IconUri = "Images/Beer.png", Type = "NotDetermined" };  
  8.             Data item2 = new Data() { Name = "Fries", IconUri = "Images/fries.png", Type = "Unhealthy" };  
  9.             Data item3 = new Data() { Name = "Sandwich", IconUri = "Images/Hamburger.png", Type = "Unhealthy" };  
  10.             Data item4 = new Data() { Name = "Ice-cream", IconUri = "Images/icecream.png", Type = "Healthy" };  
  11.             Data item5 = new Data() { Name = "Pizza", IconUri = "Images/Pizza.png", Type = "Unhealthy" };  
  12.             Data item6 = new Data() { Name = "Pepper", IconUri = "Images/Pepper.png", Type = "Healthy" };  
  13.             list.Add(item0);  
  14.             list.Add(item1);  
  15.             list.Add(item2);  
  16.             list.Add(item3);  
  17.             list.Add(item4);  
  18.             list.Add(item5);  
  19.             list.Add(item6);  
  20.   
  21.             this.listBox.ItemsSource = list;  
  22.                   
  23.   }  


下一步要做的是建立三个DataTemplates 并且把它们分别设定成ListBox的一个ItemTemplate。因为这三个DataTemplate都是独立的相互之间没有联系,这意味着你可以在每个DataTemplate上使用任何的element。因此一个数据源可以三种不同的显示。

左边的是效果图,这是这三个DataTemplates 的模样:

                                                                              

          


建立 ListBox的源码如下:

 
  1. <ListBox x:Name="listBox" HorizontalContentAlignment="Stretch">  
  2.     <ListBox.ItemTemplate>  
  3.         <DataTemplate>  
  4.             <local:FoodTemplateSelector Content="{Binding}">  
  5.                 <local:FoodTemplateSelector.Healthy>  
  6.                     <DataTemplate>  
  7.                         <StackPanel Orientation="Horizontal" Background="YellowGreen" Width="400" Margin="10">  
  8.                             <Image Source="{Binding IconUri}" Stretch="None"/>  
  9.                             <TextBlock Text="{Binding Name}" FontSize="40" Foreground="Black" Width="280"/>  
  10.                             <TextBlock Text="healty" />  
  11.                         </StackPanel>  
  12.                     </DataTemplate>  
  13.                     </local:FoodTemplateSelector.Healthy>  
  14.                 <local:FoodTemplateSelector.UnHealthy>  
  15.                     <DataTemplate>  
  16.                         <Border BorderBrush="Red" BorderThickness="2"  Width="400" Margin="10">  
  17.                         <StackPanel Orientation="Horizontal">  
  18.                             <Image Source="{Binding IconUri}" Stretch="None"/>  
  19.                                 <TextBlock Text="{Binding Name}" FontSize="40" Width="280"/>  
  20.                             <Image Source="Images/attention.png" Stretch="None" Margin="10,0,0,0"/>  
  21.                         </StackPanel>  
  22.                         </Border>  
  23.                     </DataTemplate>  
  24.                 </local:FoodTemplateSelector.UnHealthy>  
  25.                 <local:FoodTemplateSelector.NotDetermined>  
  26.                     <DataTemplate>  
  27.                         <StackPanel Orientation="Horizontal" Background="Gray" Width="400" Margin="10">  
  28.                             <Image Source="{Binding IconUri}" Stretch="None"/>  
  29.                             <TextBlock Text="{Binding Name}" FontSize="40" Width="280"/>  
  30.                             <Image Source="Images/question.png" Stretch="None" Margin="10,0,0,0"/>  
  31.                         </StackPanel>  
  32.                     </DataTemplate>  
  33.                 </local:FoodTemplateSelector.NotDetermined>  
  34.             </local:FoodTemplateSelector>  
  35.         </DataTemplate>  
  36.     </ListBox.ItemTemplate>  
  37. </ListBox>  

最终的结果:ListBox的每一个item由于不同的Type属性值都有不同的template 。

        

这里贴出有用的链接,提供了实现DataTemplateSelector  的途径:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值