Creazione di un Xamarin.Forms oggetto DataTemplateSelector
È possibile usare un DataTemplateSelector per scegliere un DataTemplate in fase di esecuzione in base al valore di una proprietà associata a dati. Questo consente di applicare più DataTemplate allo stesso tipo di oggetto, per personalizzare l'aspetto di oggetti specifici. Questo articolo illustra come creare e utilizzare un DataTemplateSelector.
Un selettore di modello di dati rende possibili scenari come l'associazione di un controllo ListView
a una raccolta di oggetti, in cui l'aspetto di ogni oggetto nel controllo ListView
può essere scelto in fase di esecuzione dal selettore del modello di dati con la restituzione di un particolare DataTemplate
.
Creazione di un DataTemplateSelector
Un selettore del modello di dati viene implementato tramite la creazione di una classe che eredita da DataTemplateSelector
. Il metodo OnSelectTemplate
è quindi sottoposto a override per restituire un particolare DataTemplate
, come illustrato nell'esempio di codice seguente:
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;
}
}
Il metodo OnSelectTemplate
restituisce il modello appropriato in base al valore della proprietà DateOfBirth
. Il modello da restituire è il valore della proprietà ValidTemplate
o della proprietà InvalidTemplate
, impostata quando si utilizza PersonDataTemplateSelector
.
È quindi possibile assegnare un'istanza della classe del selettore del modello di dati alle proprietà del Xamarin.Forms controllo, ListView.ItemTemplate
ad esempio . Per un elenco delle proprietà valide, vedere Creazione di un oggetto DataTemplate.
Limiti
Le istanze di DataTemplateSelector
presentano le limitazioni seguenti:
- La sottoclasse
DataTemplateSelector
deve sempre restituire lo stesso modello per gli stessi dati, se sottoposti a query più volte. - La sottoclasse
DataTemplateSelector
non deve restituire un'altra sottoclasseDataTemplateSelector
. - La sottoclasse
DataTemplateSelector
non deve restituire nuove istanze di unDataTemplate
per ogni chiamata. Al contrario, deve essere restituita la stessa istanza. In caso contrario, si creerà una perdita di memoria e la virtualizzazione verrà disabilitata. - In Android, non possono esistere più di 20 modelli di dati diversi per ogni
ListView
.
Utilizzo di un DataTemplateSelector in XAML
In XAML, è possibile creare un'istanza di PersonDataTemplateSelector
dichiarandolo come risorsa, come illustrato nell'esempio di codice seguente:
<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>
Questo ResourceDictionary
a livello di pagina definisce due istanze di DataTemplate
e un'istanza di PersonDataTemplateSelector
. L'istanza di PersonDataTemplateSelector
imposta le relative proprietà ValidTemplate
e InvalidTemplate
sulle istanze di DataTemplate
appropriate usando l'estensione di markup StaticResource
. Si noti che anche se le risorse sono definite nel ResourceDictionary
della pagina, possono essere definite anche a livello di controllo o di applicazione.
L'istanza di PersonDataTemplateSelector
viene utilizzata assegnandola alla proprietà ListView.ItemTemplate
, come illustrato nell'esempio di codice seguente:
<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" />
In fase di esecuzione, ListView
chiama il metodo PersonDataTemplateSelector.OnSelectTemplate
per ognuno degli elementi nella raccolta sottostante, con il passaggio dell'oggetto dati come parametro item
nella chiamata. Il DataTemplate
restituito dal metodo viene quindi applicato a tale oggetto.
Gli screenshot seguenti illustrano il risultato dell'applicazione del PersonDataTemplateSelector
da parte del controllo ListView
a ogni oggetto nella raccolta sottostante:
Qualsiasi oggetto Person
con un valore della proprietà DateOfBirth
maggiore o uguale a 1980 viene visualizzato in verde, mentre gli oggetti rimanenti vengono visualizzati in rosso.
Utilizzo di un oggetto DataTemplateSelector in C#
In C#, è possibile creare un'istanza di PersonDataTemplateSelector
e assegnarlo alla proprietà ListView.ItemTemplate
, come illustrato nell'esempio di codice seguente:
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'istanza di PersonDataTemplateSelector
imposta le proprietà ValidTemplate
e InvalidTemplate
sulle istanze di DataTemplate
appropriate create dal metodo SetupDataTemplates
. In fase di esecuzione, ListView
chiama il metodo PersonDataTemplateSelector.OnSelectTemplate
per ognuno degli elementi nella raccolta sottostante, con il passaggio dell'oggetto dati come parametro item
nella chiamata. Il DataTemplate
restituito dal metodo viene quindi applicato a tale oggetto.
Riepilogo
In questo articolo è stato illustrato come creare e utilizzare un DataTemplateSelector
. È possibile usare un DataTemplateSelector
per scegliere un DataTemplate
in fase di esecuzione in base al valore di una proprietà associata ai dati. Questo consente di applicare più istanze di DataTemplate
allo stesso tipo di oggetto, per personalizzare l'aspetto di oggetti specifici.