创建 Xamarin.Forms DataTemplateSelector
DataTemplateSelector 可用于在运行时根据数据绑定属性的值来选择 DataTemplate。 如此可将多个 DataTemplate 应用于同一类型的对象,以自定义特定对象的外观。 本文演示如何创建和使用 DataTemplateSelector。
数据模板选择器支持多种方案,例如:将 ListView
绑定到对象集合,其中返回特定 DataTemplate
的数据模板选择器可以在运行时选择 ListView
中各对象的外观。
创建 DataTemplateSelector
数据模板选择器是通过创建从 DataTemplateSelector
继承的类来实现的。 然后替代 OnSelectTemplate
方法以返回特定的 DataTemplate
,如以下代码示例所示:
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate ValidTemplate { get; set; }
public DataTemplate InvalidTemplate { get; set; }
protected override DataTemplate OnSelectTemplate (object item, BindableObject container)
{
return ((Person)item).DateOfBirth.Year >= 1980 ? ValidTemplate : InvalidTemplate;
}
}
OnSelectTemplate
方法根据 DateOfBirth
属性的值返回适当的模板。 要返回的模板是 ValidTemplate
属性或 InvalidTemplate
属性的值,这些属性是使用 PersonDataTemplateSelector
时设置的。
然后可以将数据模板选择器类的实例分配给 Xamarin.Forms 控件属性,如 ListView.ItemTemplate
。 有关有效属性的列表,请参阅创建 DataTemplate。
限制
DataTemplateSelector
实例存在以下限制:
- 如果查询多次,
DataTemplateSelector
子类必须始终为相同的数据返回相同的模板。 DataTemplateSelector
子类不能返回另一个DataTemplateSelector
子类。DataTemplateSelector
子类不能在每次调用时返回DataTemplate
的新实例。 必须返回相同的实例。 如果做不到这一点,就会造成内存泄漏并禁用虚拟化。- 在 Android 上,每个
ListView
最多只能有 20 个不同的数据模板。
在 XAML 中使用 DataTemplateSelector
在 XAML 中,可以通过将 PersonDataTemplateSelector
声明为资源来对它进行实例化,如以下代码示例所示:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:Selector;assembly=Selector" x:Class="Selector.HomePage">
<ContentPage.Resources>
<ResourceDictionary>
<DataTemplate x:Key="validPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<DataTemplate x:Key="invalidPersonTemplate">
<ViewCell>
...
</ViewCell>
</DataTemplate>
<local:PersonDataTemplateSelector x:Key="personDataTemplateSelector"
ValidTemplate="{StaticResource validPersonTemplate}"
InvalidTemplate="{StaticResource invalidPersonTemplate}" />
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
此页面级别 ResourceDictionary
定义两个 DataTemplate
实例和一个 PersonDataTemplateSelector
实例。 通过使用 StaticResource
标记扩展,PersonDataTemplateSelector
实例将其 ValidTemplate
和 InvalidTemplate
属性设置为相应的 DataTemplate
实例。 请注意,虽然资源是在页面的 ResourceDictionary
中定义的,但也可以在控件级别或应用程序级别定义。
通过将 PersonDataTemplateSelector
实例分配给 ListView.ItemTemplate
属性来使用它,如下面的代码示例所示:
<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" />
在运行时,ListView
为基础集合中的每个项调用 PersonDataTemplateSelector.OnSelectTemplate
方法,调用将数据对象作为 item
参数传递。 然后将方法返回的 DataTemplate
应用于该对象。
以下屏幕截图显示了 ListView
对基础集合中的每个对象应用 PersonDataTemplateSelector
的结果:
任何 DateOfBirth
属性值大于或等于 1980 的 Person
对象都以绿色显示,其余对象以红色显示。
在 C# 中使用 DataTemplateSelector
在 C# 中,可以实例化 PersonDataTemplateSelector
并将其分配给 ListView.ItemTemplate
属性,如下面的代码示例所示:
public class HomePageCS : ContentPage
{
DataTemplate validTemplate;
DataTemplate invalidTemplate;
public HomePageCS ()
{
...
SetupDataTemplates ();
var listView = new ListView {
ItemsSource = people,
ItemTemplate = new PersonDataTemplateSelector {
ValidTemplate = validTemplate,
InvalidTemplate = invalidTemplate }
};
Content = new StackLayout {
Margin = new Thickness (20),
Children = {
...
listView
}
};
}
...
}
PersonDataTemplateSelector
实例将其 ValidTemplate
和 InvalidTemplate
属性设置为由 SetupDataTemplates
方法创建的相应的 DataTemplate
实例。 在运行时,ListView
为基础集合中的每个项调用 PersonDataTemplateSelector.OnSelectTemplate
方法,调用将数据对象作为 item
参数传递。 然后将方法返回的 DataTemplate
应用于该对象。
总结
本文演示如何创建和使用 DataTemplateSelector
。 DataTemplateSelector
可用于在运行时根据数据绑定属性的值来选择 DataTemplate
。 如此可将多个 DataTemplate
实例应用于同一类型的对象,以自定义特定对象的外观。