DataTemplateSelector: Verschiedene DataTemplates für eine Liste

Normalerweise definiert man ein einzelnes Template für Elemente einer Liste, so dass jedes Element gleich dargestellt wird. Aber manchmal möchte man abhängig von den jeweiligen Daten ein anderes Template verwenden, so dass man auf einmal zwei oder auch mehr Templates benötigt. An dieser Stelle kommt nun der DataTemplateSelector ins Spiel. Dieser ermöglicht nämlich genau dieses Szenario, dass man abhängig von den Daten verschiedene Templates anwenden kann. Wie das im Einzelnen funktioniert, möchte ich euch in diesem Beitrag zeigen.

Geben wir davon aus, dass wir bereits ein Datenmodell haben, welches auf den Namen CustomItem hört und eine Property MyProperty vom Typ bool zur Verfügung stellt. Dann können wir nun einen DataTemplateSelector schreiben, wie das folgende Code-Snippet zeigt:

public class CustomDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate CustomTemplateA { get; set; }
    public DataTemplate CustomTemplateB { get; set; }

    protected override DataTemplate OnSelectTemplate (object item, 
        BindableObject container)
    {
        // define logic to select the correct template
        if (item is CustomItem customItem)
        {
            return customItem.MyProperty
                ? CustomTemplateA
                : CustomTemplateB;
        }

        return null;
    }
}

Es wird somit die Property MyProperty ausgewertet und entweder CustomTemplateA oder CustomTemplateB zurückgegeben.

Nun haben wir die Logik bereit geschrieben, aber wie können wir den DataTemplateSelector nun verwenden? Hierzu legen wir nun zwei passende Ressourcen an und ebenso eine Instanz von unserem CustomDataTemplateSelector.

<ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="CustomTemplateA">
                <local:CustomControlA />
            </DataTemplate>
            <DataTemplate x:Key="CustomTemplateB">
                <local:CustomControlB />
            </DataTemplate>
             <local:CustomDataTemplateSelector 
                 x:Key="CustomDataTemplateSelector" 
                 CustomTemplateA="{StaticResource CustomTemplateA}" 
                 CustomTemplateB="{StaticResource CustomTemplateB}" />
        </ResourceDictionary>
    </ContentPage.Resources>
     <ListView ItemTemplate="{StaticResource CustomDataTemplateSelector}"
               ItemSource="{Binding MyItems}">
    </ListView>
</ContentPage>

An dieser Stelle noch ein kleiner Hinweis, dass man einen DataTemplateSelector nur dann verwenden sollte, wenn sich das Layout der einzelnen Zellen wirklich stark unterscheidet. Denn die Verwendung kann Auswirkungen auf die Performance haben, da jede Zelle einzelnen gerendert werden muss und das Caching der ListView erschwert wird. Insgesamt ist es aber eine tolle Sache, um je nach den verwendeten Daten der Zelle ein anderes Layout zu verpassen.

Entwickleroptionen unter Android aktivieren XF: Custom Control – LabeledSwitch Xamarin.Forms Controls: RepeaterView