Creazione di un Xamarin.Forms oggetto DataTemplateSelector

Download Sample Scaricare l'esempio

È 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.ItemTemplatead 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 sottoclasse DataTemplateSelector.
  • La sottoclasse DataTemplateSelector non deve restituire nuove istanze di un DataTemplate 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:

ListView with a Data Template Selector

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.