• [译]实现Windows Phone 7 下的DataTemplateSelector 和 CustomDataTemplateSelector


      在这片文章中我将解释如何在Silverlight for Windows Phone7中创建一个DataTemplateSelector抽象类以及CustomDataTemplateSelector。DataTemplateSelector可以基于数据对象和数据绑定提供一种方式去选择DataTemplate。特殊情况下,当你对于同一种对象有多个DataTemplate并且你想要按照自己的逻辑去选择DataTemplate应用到各个数据对象的属性的时候需要一些DataTemplateSelector。

      总之,DataTemplateSelector使你对于一些特殊项,可以写一些逻辑选择使用哪种DataTemplate。如果有必要,你甚至可以创建一个新的数据模板。

      注意:DataTemplateSelector在WPF是一个众所周知的类,但是在Silverlight中不支持。

      下面是我在开发者论坛中看到的一个很流行的问题:“我有一列不同类型的元素,我想针对不同的列表元素基于它的类型显示不同的数据模板。”

      这个问题的答案就是使用DataTemplateSelector。因此在这篇文章中我会首先解释如何实现DataTemplateSelector抽象类并且证明如何实现你自己的CustomDataTemplateSelector。最后的结果会显示在右边的图中。

    实现DataTemplateSelector抽象类

      有许多不同的方式创建一个动态的DataTemplateSelector。你可以从WPF的实现中获取一些代码或者尝试用ValueConverter等等。在这篇文章中我将展示利用ContentControl如何创建一个DataTemplateSelector(我将用ContentControl作为基类)。

      我首先将要创建一个包含SelectTemplate虚方法的抽象类,此方法返回一个基于Prority属性值的恰当的模板(当在任何为DataTemplateSelector的分部类中重载时)。我将同时重载来自基类的OnContentChanged方法。源代码如下:

    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);
    }
    }

     

    如何创建一个CustomDataTemplateSelector

      为了创建CustomDataTemplateSelector,首先创建一个冲DataTemplateSelector类继承的类,并且重载SelectorTemplate方法。一旦你的类定义好之后,你就可以把这个类的实例指定给你的界面元素的template selector property。

      我将创建FoodTemplateSelector类,它包括三个不同DataTemplates:Healthy,UnHealthy以及NotDetermined。在SelectorTemplate方法中我将添加一些条件语句来选择合适的DataTemplate。我将基于Data的Type属性值选择正确的模板。

    FoodTemplateSelector类源代码如下:

    public class FoodTemplateSelector : DataTemplateSelector
    {
    public DataTemplate Healthy
    {
    get;
    set;
    }

    public DataTemplate UnHealthy
    {
    get;
    set;
    }

    public DataTemplate NotDetermined
    {
    get;
    set;
    }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
    Data foodItem = item as Data;

    if (foodItem != null)
    {
    if (foodItem.Type == "Healthy")
    {
    return Healthy;
    }
    else if (foodItem.Type == "NotDetermined")
    {
    return NotDetermined;
    }
    else
    {
    return UnHealthy;
    }
    }
    return base.SelectTemplate(item, container);
    }
    }

     

    以下是Data类:

    public class Data
    {
        public string Name
        {
            get;
            set;
        }
    
        public string Description
        {
            get;
            set;
        }
    
        public string IconUri
        {
            get;
            set;
        }
     
        public string Type
        {
            get;
            set;
        }
    }
    

    为了展示FoodTemplateSelector的作用,我将利用ListBox进行数据绑定。下面是源代码:

            public MainPage()
            {
                InitializeComponent();
    
                List<Data> list = new List<Data>();
                Data item0 = new Data() { Name = "Tomato", IconUri = "Images/Tomato.png", Type = "Healthy" };
                Data item1 = new Data() { Name = "Beer", IconUri = "Images/Beer.png", Type = "NotDetermined" };
                Data item2 = new Data() { Name = "Fries", IconUri = "Images/fries.png", Type = "Unhealthy" };
                Data item3 = new Data() { Name = "Sandwich", IconUri = "Images/Hamburger.png", Type = "Unhealthy" };
                Data item4 = new Data() { Name = "Ice-cream", IconUri = "Images/icecream.png", Type = "Healthy" };
                Data item5 = new Data() { Name = "Pizza", IconUri = "Images/Pizza.png", Type = "Unhealthy" };
                Data item6 = new Data() { Name = "Pepper", IconUri = "Images/Pepper.png", Type = "Healthy" };
                list.Add(item0);
                list.Add(item1);
                list.Add(item2);
                list.Add(item3);
                list.Add(item4);
                list.Add(item5);
                list.Add(item6);
                this.listBox.ItemsSource = list;
            }
    

      

    然后我将创建三个不同的DataTemplate并且将他们只是为ListBox的ItemTemplate。注意每一个Template是独立的,并且与其它没有联系。这意味着你可以在每个Template中自由添加你想要的任何元素。因此你可以用三种不同的方式展示一个数据源。

      最后的结果如左图所示。

    下面是每个模板的样式:

     

     

    以下是源代码:

    <ListBox x:Name="listBox" HorizontalContentAlignment="Stretch">
    <ListBox.ItemTemplate>
    <DataTemplate>
    <local:FoodTemplateSelector Content="{Binding}">
    <local:FoodTemplateSelector.Healthy>
    <DataTemplate>
    <StackPanel Orientation="Horizontal" Background="YellowGreen" Width="400" Margin="10">
    <Image Source="{Binding IconUri}" Stretch="None"/>
    <TextBlock Text="{Binding Name}" FontSize="40" Foreground="Black" Width="280"/>
    <TextBlock Text="healty" />
    </StackPanel>
    </DataTemplate>
    </local:FoodTemplateSelector.Healthy>
    <local:FoodTemplateSelector.UnHealthy>
    <DataTemplate>
    <Border BorderBrush="Red" BorderThickness="2" Width="400" Margin="10">
    <StackPanel Orientation="Horizontal">
    <Image Source="{Binding IconUri}" Stretch="None"/>
    <TextBlock Text="{Binding Name}" FontSize="40" Width="280"/>
    <Image Source="Images/attention.png" Stretch="None" Margin="10,0,0,0"/>
    </StackPanel>
    </Border>
    </DataTemplate>
    </local:FoodTemplateSelector.UnHealthy>
    <local:FoodTemplateSelector.NotDetermined>
    <DataTemplate>
    <StackPanel Orientation="Horizontal" Background="Gray" Width="400" Margin="10">
    <Image Source="{Binding IconUri}" Stretch="None"/>
    <TextBlock Text="{Binding Name}" FontSize="40" Width="280"/>
    <Image Source="Images/question.png" Stretch="None" Margin="10,0,0,0"/>
    </StackPanel>
    </DataTemplate>
    </local:FoodTemplateSelector.NotDetermined>
    </local:FoodTemplateSelector>
    </DataTemplate>
    </ListBox.ItemTemplate>
    </ListBox>

     

    最终的结果:ListBox的每一项根据不同的Type属性值使用不同的template。

    以下是实现DataTemplateSelector的其他途径链接:

    这就是所有关于如何实现DataTemplateSelector抽象类的方法,并且在Silverlight for windows phone 7中如何使用它。你可以在这里找到源代码:WP7SampleProject10.zip

    希望这篇文章对你有帮助。

  • 相关阅读:
    JavaScript 时间帮助封装
    EntityFramework 基类重写
    sql server 大数据, 统计分组查询,数据量比较大计算每秒钟执行数据执行次数
    C# DataTable 转实体对象
    EF自动创建数据库步骤之四(启用数据库初始器)
    EF自动创建数据库步骤之三(自定义数据库初始器)
    EF自动创建数据库步骤之二(继承DbContext类)
    EF自动创建数据库步骤之一(实体类写法)
    十大排序算法_java实现
    位运算
  • 原文地址:https://www.cnblogs.com/lujiao_cs/p/2251658.html
Copyright © 2020-2023  润新知