MAUI新生3.4-深入理解XAML:数据模板DataTemplate

数据模板主要作用是定义集合类控件的数据显示外观,和前面几个章节自定义控件的关系不大。数据模板本质上是定义集合的每一个迭代对象的UI,和Vue的v-for或Blazor的foreach类似。数据模板可以直接在控件内部定义(内联数据模板),也可以定义在控件级、页面级或应用级的资源字典中。

 

一、内联 数据模板的定义和使用

<ContentPage
    ......
    xmlns:model="clr-namespace:MauiApp10.Models">
    <VerticalStackLayout>
        <CollectionView>
            <!--属性ItemsSource设置数据源,使用泛型Array<T>集合-->
            <CollectionView.ItemsSource>
                <x:Array Type="{x:Type model:Employee}">
                    <model:Employee Id="1" Name="zs" EntryDate="2021-01-01" />
                    <model:Employee Id="2" Name="ls" EntryDate="2021-05-01" />
                    <model:Employee Id="3" Name="ww" EntryDate="2021-07-01" />
                </x:Array>
            </CollectionView.ItemsSource>
            <!--属性ItemTemplate设置数据模板,Item指迭代集合的每一行-->
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid ColumnDefinitions="1*,2*,3*">
                        <Label Grid.Column="0" HorizontalOptions="Center" Text="{Binding Id}" />
                        <Label Grid.Column="1" HorizontalOptions="Center" Text="{Binding Name}" />
                        <Label Grid.Column="2" HorizontalOptions="Center" Text="{Binding EntryDate}" />
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </VerticalStackLayout>
</ContentPage>

 

 

二、资源字典 数据模板的定义和使用

<ContentPage
    ......
    xmlns:model="clr-namespace:MauiApp10.Models">
    <!--定义页面级资源字典-->
    <ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="employeeTemplate">
                <Grid ColumnDefinitions="1*,2*,3*">
                        <Label Grid.Column="0" HorizontalOptions="Center" Text="{Binding Id}" />
                        <Label Grid.Column="1" HorizontalOptions="Center" Text="{Binding Name}" />
                        <Label Grid.Column="2" HorizontalOptions="Center" Text="{Binding EntryDate}" />
                 </Grid>
            </DataTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>

    <VerticalStackLayout>
        <!--直接设置ItemTemplate属性,引用静态资源-->
        <CollectionView ItemTemplate="{StaticResource employeeTemplate}">
            <CollectionView.ItemsSource>
                <x:Array Type="{x:Type model:Employee}">
                    <model:Employee Id="1" Name="zs" EntryDate="2021-01-01" />
                    <model:Employee Id="2" Name="ls" EntryDate="2021-05-01" />
                    <model:Employee Id="3" Name="ww" EntryDate="2021-07-01" />
                </x:Array>
            </CollectionView.ItemsSource>
        </CollectionView>
    </VerticalStackLayout>
</ContentPage>

 

 

三、控件模板也可以作为数据模板使用

<!--控件模板-->
<ContentView
    ......>

    <Grid ColumnDefinitions="1*,2*,3*">
        <Label Grid.Column="0" HorizontalOptions="Center" Text="{Binding Id}" />
        <Label Grid.Column="1" HorizontalOptions="Center" Text="{Binding Name}" />
        <Label Grid.Column="2" HorizontalOptions="Center" Text="{Binding EntryDate}" />
    </Grid>
</ContentView>


<!--DataTemplate为控件模板实例化对象-->
<CollectionView>
    <CollectionView.ItemsSource>
        ......
    </CollectionView.ItemsSource>
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <control:EmployeeView />
         </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

 

 

 四、使用DataTemplateSelector(数据模板选择器),根据条件更改Item行样式。类似于在Vue或Blazor的循环中使用的if,但XAML使用for或者if会麻烦非常多,这也是XAML被诟病的地方。以下直接扒文档案例。

1、第一步,定义数据模板选择器类,派生自DataTemplateSelector

public class PersonDataTemplateSelector : DataTemplateSelector
{
    //定义两个数据模板属性
    public DataTemplate ValidTemplate { get; set; }
    public DataTemplate InvalidTemplate { get; set; }
    //参数item为集合控件的迭代对象,参数container为集合控件对象
    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        //返回值为数据模板
        //根据出生日期,使用不同的数据模板
        return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;
    }
}

 

2、第二步,在资源字典中定义数据模板和数据模板选择器

<ContentPage.Resources>
    <!--定义数据模板validPersonTemplate-->
    <DataTemplate x:Key="validPersonTemplate">
        ...
    </DataTemplate>
    <!--定义数据模板invalidPersonTemplate-->
    <DataTemplate x:Key="invalidPersonTemplate">
        ...
    </DataTemplate>
    <!--实例化数据模板选择器对象-->
    <local:PersonDataTemplateSelector x:Key="personDataTemplateSelector"
                                      ValidTemplate="{StaticResource validPersonTemplate}"
                                      InvalidTemplate="{StaticResource invalidPersonTemplate}" />
</ContentPage.Resources>

 

3、第三步,使用数据模板选择器

<CollectionView  ItemTemplate="{StaticResource personDataTemplateSelector}" .../>

 

posted @ 2022-12-06 22:29  functionMC  阅读(531)  评论(0编辑  收藏  举报