新文章 网摘 文章 随笔 日记

DataTemplateSelector

假设您有一个项目集合,并且想要在ListView(Xamarin.Forms)中显示它们。要注意的是,您要根据项目的状态或其他基于代码的属性来更改其显示。

乍一看,这似乎非常困难,您必须修改集合中的实例才能这样做。这是DataTemplateSelector出现的地方。

简而言之,您将创建两个或多个数据模板(每种可能会希望显示集合中项目之一的模板),然后通过DataTemplateSelector告诉Xamarin.Forms使用哪个数据模板。

用一个简单的例子可能更容易理解。

让我们从将在集合中显示的类型开始。

 public class Mood
 {
     public string CurrentMood { get; set; }
 }

如您所见,我们正在使用一个非常简单的类型。现在,让我们创建一个Mood对象的集合(在我们的ViewModel中):

public class MyListPageViewModel
{
    public ObservableCollection<Mood> Moods { get; set;  }
    
    public MyListPageViewModel()
    {
        Moods = new ObservableCollection<Mood>();
        PopulateCollection();
    }

    private void PopulateCollection()
    {
        var mood = new Mood { CurrentMood = "Happy" };
        Moods.Add(mood);
        mood = new Mood { CurrentMood = "Happy" };
        Moods.Add(mood);
        mood = new Mood { CurrentMood = "Sad" };
        Moods.Add(mood);
        mood = new Mood { CurrentMood = "Happy" };
        Moods.Add(mood);
        mood = new Mood { CurrentMood = "Sad" };
        Moods.Add(mood);
    }
}

如您所见,我们有一个名为Moods的Mood对象的集合,并且我们用五个实例填充了该集合,有些实例是快乐的,有些实例是悲伤的。

现在,我们创建我们的DataTemplates,其中一个用于具有CurrentMood值为“ Happy”的Mood对象,另一个是用于CurrentMood值为“ Sad”的对象。(这在我们的xaml文件中)

 <ContentPage.Resources>
     <ResourceDictionary>
         <DataTemplate x:Key="HappyTemplate">
             <ViewCell>
             <StackLayout>
                 <Label HorizontalOptions="StartAndExpand" 
                         VerticalOptions="CenterAndExpand" 
                         Text="Happy Happy" 
                         FontSize="20"/>
             </StackLayout>
         </ViewCell>
         </DataTemplate>

         <DataTemplate x:Key="SadTemplate">
             <ViewCell>
             <StackLayout>
                 <Label Text="Sad, very sad."
                        FontSize="20"
                        TextColor="Red"
                        HorizontalOptions="StartAndExpand"
                        VerticalOptions="CenterAndExpand"/>
                 </StackLayout>
             </ViewCell>
         </DataTemplate>
         

我们有两个DataTemplates。一个拥有钥匙“ HappyTemplate”,另一个拥有钥匙“ SadTemplate”。它们之间的主要区别是SadTemplate将Label的字体颜色设置为红色。

当然,您可以根据需要使DataTemplates变得复杂和不同。例如,可能有。包含三列的agrid,其中第一列是图像,另一列可能使用StackLayout而没有图像。

接下来是ListView的声明,乐趣开始了……

 <ContentPage.Content>
     <StackLayout VerticalOptions="FillAndExpand">
         <ListView   
             HasUnevenRows="True"
             ItemTemplate="{StaticResource DemoTemplateSelector}"
             ItemsSource="{Binding Moods}"
             SeparatorVisibility="None"
             VerticalOptions="StartAndExpand" 
             Margin="5">
         </ListView>
     </StackLayout>
 </ContentPage.Content>

这里要注意的关键是将ItemTemplate设置为DemoTemplate Selector。这是XAML的一部分,位于数据模板之后和列表之前:

<templateselector:DemoTemplateSelector x:Key="DemoTemplateSelector"
                 HappyTemplate="{StaticResource HappyTemplate}"
                 SadTemplate="{StaticResource SadTemplate}" />

DataTemplateSelector与我们将在稍后看到的代码一起使用,以选择两个命名模板(HappyTemplate和SadTemplate)之一。

要选择要使用的DataTemplate,您需要一个具有逻辑的新文件。它需要从DataTemplateSelector派生。这是课程的开始:

    public class DemoTemplateSelector : DataTemplateSelector
    {
        public DataTemplate HappyTemplate { get; set; }
        public DataTemplate SadTemplate { get; set; }


        protected override DataTemplate OnSelectTemplate(
            object item, BindableObject container)
        {
            DataTemplate selectedTemplate;

            if (!(item is Mood))
            {
                throw new ArgumentException("Not a mood!");
            }

我们要做的第一件事是定义两个与XAML中的对象相对应的DataTemplate对象。接下来,我们重写OnSelectedTemplate事件处理程序,并检查以确保我们具有正确类型的对象。

假设这样做,我们想检查属性“ CurrentMood”,并为ListView中的该条目选择正确的DataTemplate:

var selectedItem = (Mood)item;

if (selectedItem.CurrentMood == "Happy")
{
    selectedTemplate = HappyTemplate;
}
else
{
    selectedTemplate = SadTemplate;
}

return selectedTemplate ?? HappyTemplate;

集合中的每个项目都传递给此方法并进行评估。返回正确的DataTemplate并在ListView中使用

此程序的完整源代码在此处

 

关于杰西·自由

杰西·利伯蒂(Jesse Liberty)在编写和交付软件项目方面拥有三十年的经验,并撰写了2本书和20多个Pluralsight和LinkedIn学习课程。他曾是Microsoft的高级技术布道者,AT&T的杰出软件工程师,花旗银行信息服务副总裁和PBS的软件架构师。他是Xamarin认证的移动开发人员,并且是Xamarin MVP和Microsoft MVP。
此项目被张贴在要点Xamarin.Forms永久链接添加书签
posted @ 2020-08-11 10:15  岭南春  阅读(171)  评论(0)    收藏  举报