Ich habe ja bereits gezeigt, wie wir ein neues Xamarin.Forms Control, nämlich die RepeaterView, erstellen und diese haben wir bereits erweitert, dass jede zweite Zeile eine andere Hintergrundfarbe bekommt. In diesem Beitrag möchte ich euch jetzt zeigen, wie ihr die RepeaterView
so ergänzen könnt, dass statt eines ItemTemplates
auch ein DataTemplateSelector
angegeben kann, welcher auf Grund verschiedener Regeln das passende Template auswählt und darstellt.
Dazu benötigen wir natürlich eine neue BindableProperty
, welche wir ItemTemplateSelectorProperty
nennen wollen.
public static readonly BindableProperty ItemTemplateSelectorProperty =
BindableProperty.Create(nameof(ItemTemplateSelector), typeof(DataTemplateSelector),
typeof(RepeaterView));
public DataTemplateSelector ItemTemplateSelector
{
get => (DataTemplateSelector)GetValue(ItemTemplateSelectorProperty);
set => SetValue(ItemTemplateSelectorProperty, value);
}
Nun müssen wir noch die Methode ViewFor
anpassen. Diese überprüft nun zunächst, ob ein ItemTemplateSelector
angegeben ist. Sollte dies der Fall sein, wird dieser verwendet, um das richtige Template zu generieren. Ansonsten greift die alte Logik und wir erstellen eine Instanz von unserem ItemTemplate.
protected virtual View ViewFor(object item, bool isEvenRow = false)
{
if (ItemTemplateSelector == null && ItemTemplate == null)
return null;
object content = null;
if (ItemTemplateSelector != null)
{
var template = ItemTemplateSelector.SelectTemplate(item, this);
if (template != null)
content = template.CreateContent();
}
else
{
content = ItemTemplate.CreateContent();
}
if (content == null)
return null;
var view = content is ViewCell viewCell ? viewCell.View : content as View;
view.BindingContext = item;
if (ItemTappedCommand != null)
AddTapGestureToChildView(view);
if (IsAlternateRowColorEnabled)
{
if (isEvenRow)
view.BackgroundColor = AlternateRowColor;
}
return view;
}
Damit haben wir unsere RepeaterView
schon soweit angepasst, dass wir anstatt eines ItemTemplates
auch einen DataTemplateSelector
angegeben können. Ich habe das bestehende Beispiel als Grundlage verwendet und unser Datenmodell um die Angabe des Geschlechts ergänzt. Bei weiblichen Personen wird soll nun eine pinke Box als Indikator dienen und bei männlichen Personen eine blaue. Dafür erstellen wir uns nun einen PersonDataTemplateSelector
, welcher vom Typ DataTemplateSelector
ableitet.
public class PersonDataTemplateSelector : DataTemplateSelector
{
public DataTemplate FemaleDataTemplate { get; set; }
public DataTemplate MaleDataTemplate { get; set; }
protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
{
if (item is Person person)
{
switch (person.Gender)
{
case Gender.Male:
return MaleDataTemplate;
case Gender.Female:
return FemaleDataTemplate;
}
}
return null;
}
}
Nun können wir in XAML eine Instanz des PersonDataTemplateSelectors
erstellen und müssen nur die beiden DataTemplates
angeben.
<utils:PersonDataTemplateSelector
x:Key="PersonDataTemplateSelector"
FemaleDataTemplate="{StaticResource FemaleDataTemplate}"
MaleDataTemplate="{StaticResource MaleDataTemplate}" />
Somit erhalten wir in unserem Beispiel die folgende Ausgabe:
Das gesamte Beispiel befindet sich natürlich wieder auf GitHub und steht jedem für Erweiterungen zur Verfügung.