本文原文见WindowGeek。
在Window Phone中,我们常常遇到一些情形,譬如在ListBox中,我们要根据具体的Data来决定该如何显示当前项。这可以通过DataTemplateSelector来实现。
实现DataTemplateSelector抽象类
public abstract class DataTemplateSelector : ContentControl { public virtual DataTemplate SelectTemplate(object item, DependencyObject container) { return null; } protected override void OnContentChanged(object oldContent, object newContent) { base.OnContentChanged(oldContent, newContent); ContentTemplate = SelectTemplate(newContent, this); } }
创建你自己的数据模板选择器
public class RSSTemplateSelector : DataTemplateSelector { public DataTemplate MixedTextImgTemplate { get; set; } public DataTemplate ImgTemplate { get; set; } public DataTemplate TextTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { RssItemResp rss = item as RssItemResp; if (rss != null) { if (!CommonUtil.isEmpty(rss.Image) && !CommonUtil.isEmpty(rss.Description)) { return MixedTextImgTemplate; } else if (CommonUtil.isEmpty(rss.Image) && !CommonUtil.isEmpty(rss.Description)) { return TextTemplate; } else if (CommonUtil.isEmpty(rss.Description) && !CommonUtil.isEmpty(rss.Image)) { return ImgTemplate; } } return base.SelectTemplate(item, container); } }
定义XAML文件
<ListBox.ItemTemplate> <DataTemplate> <local:RSSTemplateSelector Content="{Binding}"> <local:RSSTemplateSelector.MixedTextImgTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="12"/> <RowDefinition Height="*"/> <RowDefinition Height="12"/> </Grid.RowDefinitions> <Image Grid.Row="0" Width="Auto" Source="Images/paperview_top.png"/> <Grid Grid.Row="1" Style="{StaticResource PaperItemMiddle}" Width="Auto"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="*"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Grid.Row="0" Text="{Binding Title}" Style="{StaticResource PaperItemTitle}"/> <TextBlock Grid.Row="1" Text="{Binding UpdateTime}" Style="{StaticResource PaperItemUpdateTime}"/> <StackPanel Grid.Row="2" Orientation="Horizontal" Height="Auto"> <TextBlock Text="{Binding Description}" Style="{StaticResource PaperItemDescription}"/> <Image Source="{Binding Image}" Height="100" Width="100" Margin="0,2,3,5"/> </StackPanel> </Grid> <Image Grid.Row="2" Width="Auto" Source="Images/paperview_bottom.png"/> </Grid> </DataTemplate> </local:RSSTemplateSelector.MixedTextImgTemplate> <local:RSSTemplateSelector.ImgTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="12"/> <RowDefinition Height="*"/> <RowDefinition Height="12"/> </Grid.RowDefinitions> <Image Grid.Row="0" Width="Auto" Source="Images/paperview_top.png"/> <StackPanel Grid.Row="1" Orientation="Vertical"> <TextBlock Text="{Binding Title}" Style="{StaticResource PaperItemTitle}"/> <TextBlock Text="{Binding UpdateTime}" Style="{StaticResource PaperItemUpdateTime}" /> <StackPanel Orientation="Horizontal" Height="60"> <Image Source="{Binding Image}"/> </StackPanel> </StackPanel> <Image Grid.Row="2" Width="Auto" Source="Images/paperview_bottom.png"/> </Grid> </DataTemplate> </local:RSSTemplateSelector.ImgTemplate> <local:RSSTemplateSelector.TextTemplate> <DataTemplate> <Grid> <Grid.RowDefinitions> <RowDefinition Height="12"/> <RowDefinition Height="*"/> <RowDefinition Height="12"/> </Grid.RowDefinitions> <Image Grid.Row="0" Width="Auto" Source="Images/paperview_top.png"/> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding Title}" Style="{StaticResource PaperItemTitle}"/> <TextBlock Text="{Binding UpdateTime}" Style="{StaticResource PaperItemUpdateTime}"/> <StackPanel Orientation="Horizontal" Height="60"> <TextBlock Text="{Binding Description}" Style="{StaticResource PaperItemDescription}"/> </StackPanel> </StackPanel> <Image Grid.Row="2" Width="Auto" Source="Images/paperview_bottom.png"/> </Grid> </DataTemplate> </local:RSSTemplateSelector.TextTemplate> </local:RSSTemplateSelector> </DataTemplate> </ListBox.ItemTemplate>
综上,我们就可以实现为ListBox提供动态模板了。