Erstellen einer DataTemplateSelector-Klasse in Xamarin.Forms

Beispiel herunterladen Das Beispiel herunterladen

Eine DataTemplateSelector-Klasse kann verwendet werden zum Auswählen einer DataTemplate-Klasse zur Laufzeit, basierend auf dem Wert der datengebundenen Eigenschaft. Dadurch können mehrere DataTemplate-Klassen auf den gleichen Objekttyp angewendet werden, um die Darstellung bestimmter Objekte anzupassen. In diesem Artikel wird veranschaulicht, wie Sie eine DataTemplateSelector-Klasse erstellen und nutzen können.

Eine Datenvorlagenauswahl ermöglicht Szenarios wie eine ListView-Bindung an eine Sammlung von Objekten, bei der die Darstellung jedes Objekts in der ListView-Klasse zur Laufzeit ausgewählt werden kann, indem durch die Datenvorlagenauswahl eine bestimmte DataTemplate-Klasse zurückgegeben wird.

Erstellen einer DataTemplateSelector-Klasse

Eine Datenvorlagenauswahl wird implementiert durch das Erstellen einer Klasse, die von der DataTemplateSelector-Klasse erbt. Die OnSelectTemplate-Methode wird dann überschrieben, um eine bestimmte DataTemplate-Klasse zurückzugeben, wie im folgenden Codebeispiel zu sehen ist:

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

Die OnSelectTemplate-Methode gibt, basierend auf dem Wert der DateOfBirth-Eigenschaft, die entsprechende Vorlage zurück. Die Vorlage, die zurückgegeben wird, ist der Wert der ValidTemplate-Eigenschaft oder der InvalidTemplate-Eigenschaft, welche bei der Nutzung der PersonDataTemplateSelector-Klasse festgelegt werden.

Eine Instanz der Datenvorlagenauswahl-Klasse kann dann Xamarin.Forms-Steuereigenschaften wie ListView.ItemTemplate zugewiesen werden. Eine Liste gültiger Eigenschaften finden Sie unter Erstellen von Datenvorlagen.

Einschränkungen

DataTemplateSelector-Instanzen weisen die folgenden Einschränkungen auf:

  • Die DataTemplateSelector-Unterklasse muss bei mehrmaligem Abfragen immer die gleiche Vorlage für dieselben Daten zurückgeben.
  • Die DataTemplateSelector-Unterklasse darf keine andere DataTemplateSelector-Unterklasse zurückgeben.
  • Die DataTemplateSelector-Unterklasse darf bei jedem Aufruf keine neuen Instanzen einer DataTemplate-Klasse zurückgeben. Stattdessen muss die gleiche Instanz zurückgegeben werden. Die Unterlassung führt zu einem Arbeitsspeicherverlust und zur Deaktivierung der Benutzeroberflächenvirtualisierung.
  • Unter Android sind nicht mehr als 20 verschiedene Datenvorlagen pro ListView-Klasse möglich.

Nutzen einer DataTemplateSelector-Klasse in XAML

In XAML kann die PersonDataTemplateSelector-Klasse instanziiert werden, indem sie als Ressource erklärt wird, wie im folgendem Codebeispiel zu sehen ist:

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

Diese ResourceDictionary-Klasse auf Seitenebene definiert zwei DataTemplate-Instanzen und eine PersonDataTemplateSelector-Instanz. Die PersonDataTemplateSelector-Instanz legt ihre ValidTemplate- und InvalidTemplate-Eigenschaften auf die entsprechenden DataTemplate-Instanzen fest, indem die StaticResource-Markuperweiterung verwendet wird. Beachten Sie, dass die Ressourcen zwar in der ResourceDictionary-Klasse der Seite definiert werden, sie aber dennoch auch auf Steuerelementebene oder Anwendungsebene definiert werden können.

Die PersonDataTemplateSelector-Instanz wird genutzt, indem sie der ListView.ItemTemplate-Eigenschaft zugewiesen wird, wie im folgenden Codebeispiel zu sehen ist:

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

Zur Laufzeit ruft die ListView-Klasse die PersonDataTemplateSelector.OnSelectTemplate-Methode für jedes Element in der zugrunde liegenden Sammlung. Dabei wird das Datenobjekt als item-Parameter übergeben. Die DataTemplate-Klasse, welche durch die Methode zurückgegeben wird, wird dann auf dieses Objekt angewendet.

Die folgenden Screenshots zeigen das Ergebnis der ListView-Klasse bei Anwendung des PersonDataTemplateSelector-Klasse auf jedes Objekt in der zugrunde liegenden Sammlung:

ListView mit einer Datenvorlagenauswahl

Jedes Person-Objekt, das einen DateOfBirth-Eigenschaftswert größer oder gleich 1980 aufweist, wird in grün angezeigt, alle übrigen Objekte werden in rot angezeigt.

Verwenden eines DataTemplateSelector in C#

In C# kann die PersonDataTemplateSelector-Klasse instanziiert und der ListView.ItemTemplate-Eigenschaft zugewiesen werden, wie im folgenden Codebeispiel zu sehen ist:

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

Die PersonDataTemplateSelector-Instanz legt ihre ValidTemplate- und InvalidTemplate-Eigenschaften auf die entsprechenden, durch die SetupDataTemplates-Methode erstellten, DataTemplate-Instanzen fest. Zur Laufzeit ruft die ListView-Klasse die PersonDataTemplateSelector.OnSelectTemplate-Methode für jedes Element in der zugrunde liegenden Sammlung. Dabei wird das Datenobjekt als item-Parameter übergeben. Die DataTemplate-Klasse, welche durch die Methode zurückgegeben wird, wird dann auf dieses Objekt angewendet.

Zusammenfassung

In diesem Artikel wurde veranschaulicht, wie eine DataTemplateSelector-Klasse erstellt und genutzt wird. Eine DataTemplateSelector kann verwendet werden, um eine DataTemplate zur Laufzeit basierend auf dem Wert der datengebundenen Eigenschaft auszuwählen. Dadurch können mehrere DataTemplate-Instanzen auf den gleichen Objekttyp angewendet werden, um die Darstellung bestimmter Objekte anzupassen.