Selezione del modello di dati: applicazione di stili agli elementi in base alle relative proprietà
La progettazione personalizzata dei controlli delle raccolte è gestita da un oggetto DataTemplate. I modelli di dati definiscono il layout e lo stile da applicare a ogni elemento e questo markup viene applicato a ogni elemento nella raccolta. Questo articolo illustra come usare un DataTemplateSelector per applicare modelli di dati diversi in una raccolta e selezionare il modello di dati da usare in base a determinate proprietà o valori di un elemento di tua scelta.
API importanti: DataTemplateSelector, DataTemplate
DataTemplateSelector è una classe che abilita la logica di selezione di modelli personalizzati. Consente di definire le regole che specificano il modello di dati da usare per determinati elementi in una raccolta. Per implementare questa logica, devi creare una sottoclasse di DataTemplateSelector nel code-behind e definire la logica che determina il modello di dati da usare per una specifica categoria di elementi (ad esempio, elementi di un determinato tipo o elementi con un determinato valore di proprietà e così via). Devi dichiarare un'istanza di questa classe nella sezione Resources del file XAML, insieme alle definizioni dei modelli di dati che userai. Queste risorse devono essere identificate con un valore x:Key
, che ti permette di farvi riferimento nel codice XAML.
Prerequisiti
- Come usare e creare un controllo di raccolta, ad esempio ListView o GridView.
- Come personalizzare l'aspetto degli elementi usando un DataTemplate.
Quando non usare un DataTemplateSelector
In generale, non è consigliabile applicare a ogni elemento in un controllo ListView o GridView un layout o uno stile completamente diverso. Non faresti un uso adeguato del DataTemplateSelector e otterresti un impatto negativo sulle prestazioni.
Alcuni elementi dell'aspetto visivo di un elemento elenco possono essere controllati usando un solo modello di dati, tramite il binding di determinate proprietà. Ad esempio, gli elementi possono avere ognuno un'icona diversa tramite il binding a una proprietà di origine dell'icona nel modello di dati e l'assegnazione a ogni elemento di un valore diverso per tale proprietà di origine dell'icona. In questo modo si ottengono prestazioni migliori rispetto all'uso di un DataTemplateSelector.
Quando usare un DataTemplateSelector
È consigliabile creare un DataTemplateSelector quando vuoi usare più modelli di dati in un unico controllo di raccolta. Un DataTemplateSelector
ti offre la flessibilità necessaria per far risaltare determinati elementi, mantenendoli comunque in un layout simile. Esistono molti casi d'uso in cui un DataTemplateSelector risulta utile e alcuni scenari in cui è preferibile riconsiderare il controllo e la strategia in uso.
I controlli della raccolta sono in genere associati a una raccolta di elementi che sono tutti dello stesso tipo. Tuttavia, anche se gli elementi possono essere dello stesso tipo, possono avere valori diversi per determinate proprietà o rappresentare significati diversi. Alcuni elementi potrebbero anche essere più importanti di altri, oppure un elemento potrebbe essere particolarmente importante o diverso e ha bisogno di risaltare visivamente. In queste situazioni, un DataTemplateSelector sarà molto utile.
Puoi anche eseguire il binding a una raccolta che contiene tipi diversi di elementi. La raccolta associata può avere una combinazione di stringhe, valori integer, oggetti classe personalizzati e altro ancora. Questo rende DataTemplateSelector particolarmente utile, in quanto può assegnare modelli di dati diversi in base al tipo di oggetto di un elemento.
Ecco alcuni esempi delle situazioni in cui potresti usare un selettore di modello di dati:
- Rappresentazione di diversi livelli di dipendenti all'interno di un controllo ListView: ogni tipo o livello di dipendente potrebbe avere bisogno di uno sfondo di colore diverso per essere facilmente distinguibile.
- Rappresentazione di articoli in vendita in una raccolta di prodotti che usa un controllo GridView: potrebbe essere necessario applicare uno sfondo rosso o un tipo di carattere di colore diverso a un articolo in vendita per distinguerlo dagli articoli con prezzo normale.
- Rappresentazione di foto che hanno vinto premi in una raccolta foto mediante FlipView.
- Necessità di rappresentare in modo diverso numeri negativi/positivi o stringhe brevi/lunghe in un controllo ListView.
Creare un oggetto DataTemplateSelector
Per creare un selettore di modello di dati, devi definire la logica di selezione del modello nel tuo codice e i modelli di dati nel codice XAML.
Componente code-behind
Per usare un selettore di modello di dati, devi creare prima una sottoclasse di DataTemplateSelector (una classe che deriva da questa classe) nel code-behind. Nella classe devi quindi dichiarare ogni modello come proprietà della classe. Occorre poi eseguire l'override del metodo SelectTemplateCore per includere la tua logica di selezione del modello.
Ecco un esempio di una semplice sottoclasse DataTemplateSelector
denominata MyDataTemplateSelector
.
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate Normal { get; set; }
public DataTemplate Accent { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
if ((int)item % 2 == 0)
{
return Normal;
}
else
{
return Accent;
}
}
}
La classe MyDataTemplateSelector
deriva dalla classe DataTemplateSelector
e definisce innanzitutto due oggetti DataTemplate: Normal
e Accent
. Per il momento sono dichiarazioni vuote, ma verranno "compilate" con il markup nel file XAML.
Il metodo SelectTemplateCore
accetta un oggetto elemento, ovvero ogni elemento della raccolta, ed è sottoposto a override con regole relative a quale DataTemplate
restituire in quali circostanze. In questo caso, se l'elemento è un numero dispari riceve il modello di dati Accent
, mentre se è un numero pari riceve il modello di dati Normal
.
Componente XAML
In secondo luogo, devi creare un'istanza di questa nuova classe MyDataTemplateSelector
nella sezione Resources del file XAML. Tutte le risorse richiedono un attributo x:Key
, che viene usato per associarlo alla proprietà ItemTemplateSelector
del controllo della raccolta (in un passaggio successivo). Devi anche creare due istanze di oggetti DataTemplate
e definirne il layout nella sezione Resources. Questi modelli di dati devono essere assegnati alle proprietà Accent
e Normal
dichiarate nella classe MyDataTemplateSelector
.
Ecco un esempio delle risorse XAML e del markup necessari:
<Page.Resources>
<DataTemplate x:Key="NormalItemTemplate" x:DataType="x:Int32">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemChromeLowColor}">
<TextBlock Text="{x:Bind}" />
</Button>
</DataTemplate>
<DataTemplate x:Key="AccentItemTemplate" x:DataType="x:Int32">
<Button HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{ThemeResource SystemAccentColor}">
<TextBlock Text="{x:Bind}" />
</Button>
</DataTemplate>
<l:MyDataTemplateSelector x:Key="MyDataTemplateSelector"
Normal="{StaticResource NormalItemTemplate}"
Accent="{StaticResource AccentItemTemplate}"/>
</Page.Resources>
Come puoi vedere, sono definiti i due modelli di dati Normal
e Accent
. Entrambi visualizzano gli elementi come pulsanti, ma il modello di dati Accent
usa un pennello di un colore principale per lo sfondo, mentre il modello di dati Normal
usa un pennello di colore grigio (SystemChromeLowColor
). Questi due modelli di dati vengono quindi assegnati agli oggetti DataTemplate Normal
e Accent
, che sono attributi della classe MyDataTemplateSelector, creati nel code-behind C#.
L'ultimo passaggio consiste nell'eseguire il binding del DataTemplateSelector
alla proprietà ItemTemplateSelector
del controllo delle raccolte (in questo caso, ListView). In questo modo non è più necessario assegnare un valore alla proprietà ItemTemplate
.
<ListView x:Name = "TestListView"
ItemsSource = "{x:Bind NumbersList}"
ItemTemplateSelector = "{StaticResource MyDataTemplateSelector}">
</ListView>
Dopo la compilazione del codice, ogni elemento della raccolta verrà eseguito tramite il metodo SelectTemplateCore
sottoposto a override in MyDataTemplateSelector
e ne verrà eseguito il rendering con il DataTemplate appropriato.
Importante
Se usi DataTemplateSelector
con un ItemsRepeater, devi eseguire il binding del DataTemplateSelector
alla proprietà ItemTemplate
. ItemsRepeater
non ha una proprietà ItemTemplateSelector
.
Considerazioni sulle prestazioni di DataTemplateSelector
Quando usi un controllo ListView o GridView con una raccolta di dati di grandi dimensioni, le prestazioni di scorrimento e panoramica possono costituire un problema. Per garantire prestazioni ottimali per le raccolte di grandi dimensioni, puoi eseguire alcune operazioni per migliorare le prestazioni dei modelli di dati. Queste operazioni sono descritte in maggiore dettaglio in Ottimizzazione dell'interfaccia utente in ListView e GridView.
- Riduzione degli elementi per modello di dati: mantieni il numero di elementi di interfaccia utente in un modello di dati entro un minimo ragionevole.
- Riciclo del contenitore con raccolte eterogenee
- Usa l'evento ChoosingItemContainer, che consente di usare modelli di dati diversi per diversi elementi assicurando prestazioni elevate. Per ottenere prestazioni ottimali, è consigliabile ottimizzare la memorizzazione nella cache e la selezione dei modelli di dati per i dati specifici.
- Usa un selettore del modello di elemento (
DataTemplateSelector
), che dovrebbe però essere evitato in alcune circostanze a causa del suo impatto sulle prestazioni.