Création d’un Xamarin.Forms DataTemplateSelector

Télécharger l’exemple Télécharger l’exemple

Vous pouvez utiliser un DataTemplateSelector pour choisir un DataTemplate au moment de l’exécution, en fonction de la valeur d’une propriété liée aux données. Cela permet d’appliquer plusieurs DataTemplates au même type d’objet pour personnaliser l’apparence d’objets particuliers. Cet article explique comment créer et consommer un DataTemplateSelector.

Avec un sélecteur de modèle de données, vous pouvez lier ListView à une collection d’objets, où l’apparence de chaque objet du ListView peut être choisie au moment de l’exécution par le sélecteur de modèle de données qui retourne un DataTemplate particulier.

Création d’un DataTemplateSelector

Vous implémentez un sélecteur de modèle de données en créant une classe qui hérite de DataTemplateSelector. La méthode OnSelectTemplate est ensuite substituée pour retourner un DataTemplate particulier, comme indiqué dans l’exemple de code suivant :

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

La méthode OnSelectTemplate retourne le modèle approprié en fonction de la valeur de la propriété DateOfBirth. Le modèle à retourner représente la valeur de la propriété ValidTemplate ou de la propriété InvalidTemplate, qui sont définies durant la consommation de PersonDataTemplateSelector.

Un instance de la classe de sélecteur de modèle de données peut ensuite être affecté à des Xamarin.Forms propriétés de contrôle telles que ListView.ItemTemplate. Pour obtenir la liste des propriétés valides, consultez Création d’un DataTemplate.

Limites

Les instances de DataTemplateSelector ont les limitations suivantes :

  • La sous-classe DataTemplateSelector doit toujours retourner le même modèle pour les mêmes données si elle est interrogée plusieurs fois.
  • La sous-classe DataTemplateSelector ne doit pas retourner une autre sous-classe DataTemplateSelector.
  • La sous-classe DataTemplateSelector ne doit pas retourner de nouvelles instances de DataTemplate à chaque appel. À la place, la même instance doit être retournée. Sinon, une fuite de mémoire se produit et la virtualisation est désactivée.
  • Sur Android, il ne peut exister plus de 20 modèles de données différents par ListView.

Consommation d’un DataTemplateSelector en XAML

En XAML, vous pouvez instancier PersonDataTemplateSelector en le déclarant en tant que ressource, comme indiqué dans l’exemple de code suivant :

<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>

Le niveau de page ResourceDictionary définit deux instances de DataTemplate et une instance de PersonDataTemplateSelector. L’instance de PersonDataTemplateSelector affecte aux propriétés ValidTemplate et InvalidTemplate les instances appropriées de DataTemplate à l’aide de l’extension de balisage StaticResource. Notez que même si les ressources sont définies dans le ResourceDictionary de la page, elles peuvent également l’être au niveau du contrôle ou de l’application.

Vous consommez l’instance de PersonDataTemplateSelector en l’affectant à la propriété ListView.ItemTemplate, comme indiqué dans l’exemple de code suivant :

<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" />

Au moment de l’exécution, ListView appelle la méthode PersonDataTemplateSelector.OnSelectTemplate pour chacun des éléments de la collection sous-jacente. Cet appel passe l’objet de données en tant que paramètre item. Le DataTemplate retourné par la méthode est ensuite appliqué à cet objet.

Les captures d’écran suivantes montrent le résultat de ListView appliquant PersonDataTemplateSelector à chaque objet de la collection sous-jacente :

ListView avec un sélecteur de modèle de données

Tout objet Person ayant une valeur de propriété DateOfBirth supérieure ou égale à 1980 est affiché en vert, les objets restants sont affichés en rouge.

Consommation d’un DataTemplateSelector en C#

En C#, vous pouvez instancier PersonDataTemplateSelector et l’affecter à la propriété ListView.ItemTemplate, comme indiqué dans l’exemple de code suivant :

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

L’instance de PersonDataTemplateSelector affecte aux propriétés ValidTemplate et InvalidTemplate les instances appropriées de DataTemplate créées par la méthode SetupDataTemplates. Au moment de l’exécution, ListView appelle la méthode PersonDataTemplateSelector.OnSelectTemplate pour chacun des éléments de la collection sous-jacente. Cet appel passe l’objet de données en tant que paramètre item. Le DataTemplate retourné par la méthode est ensuite appliqué à cet objet.

Résumé

Cet article a montré comment créer et consommer DataTemplateSelector. Vous pouvez utiliser un DataTemplateSelector pour choisir un DataTemplate au moment de l’exécution, en fonction de la valeur d’une propriété liée aux données. Cela permet d’appliquer plusieurs instances de DataTemplate au même type d’objet, pour personnaliser l’apparence d’objets en particulier.