MAUI新生3.4-深入理解XAML:資料模板DataTemplate
阿新 • • 發佈:2022-12-07
資料模板主要作用是定義集合類控制元件的資料顯示外觀,和前面幾個章節自定義控制元件的關係不大。資料模板本質上是定義集合的每一個迭代物件的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:EmployeeId="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}" .../>