Usare DataTemplateSelector in Windows Store app in XAML

di Alessio Leoncini, in WinRT,

Come abbiamo visto nello script 20 (https://www.winrtitalia.com/script/20/Mostrare-Liste-Raggruppate-sControl-Windows-Store-App.aspx), ItemsControl è uno dei controlli di base per la costruzione delle interfacce; ad arricchire le sue funzionalità possiamo trovare la proprietà ItemTemplateSelector di tipo DataTemplateSelector.

Con ItemTemplateSelector possiamo impostare una classe che differenzi il DataTemplate da usare in base alla singola entità in binding.
Riprendendo la collezione e l'esempio dello script 20, utilizziamo in binding una collezione di oggetti Person che possiamo differenziare con un oggetto SpecialPerson da cui eredita.

public class Person
{
  public string Name { get; set; }
}

public class SpecialPerson : Person { }
//..

var people = new List<GroupedPeople>
{
  new GroupedPeople()
  {
    GroupName = "Arcangeli",
    PeopleOfGroup = new List<Person>()
    {
      new Person() {Name = "Gabriele"},
      new Person() {Name = "Jehudiel"},
      new Person() {Name = "Michele"},
      new Person() {Name = "Zerachiel"}
    }
  },
  new GroupedPeople()
  {
    GroupName = "Evangelisti",
    PeopleOfGroup = new List<Person>()
    {
      new SpecialPerson() {Name = "Matteo"},
      new SpecialPerson() {Name = "Marco"},
      new SpecialPerson() {Name = "Luca"},
      new SpecialPerson() {Name = "Giovanni"}
    }
  }
};

Il polimorfismo supportato dal linguaggio non influenza il risultato, tuttavia in questo modo un DataTemplateSelector potrebbe controllare direttamente il tipo di oggetto ed applicare il giusto template.

public class SampleTemplateSelector : DataTemplateSelector
{
  public DataTemplate Template1 { get; set; }
  public DataTemplate Template2 { get; set; }
  public DataTemplate Template3 { get; set; }

  protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
  {
    if (item is SpecialPerson)
    {
      if (((SpecialPerson)item).Name == "Luca")
        return Template3;

      return Template1;
    }
    else if (item is Person)
    {
      return Template2;
    }

    return base.SelectTemplate(item, container);
  }
}

Nell'override di SelectTemplateCore, il DataTemplateSelector intercetta ogni singola entità in binding e restituisce lo specifico DataTemplate, anche in relazione ad una delle sue proprietà.
Possiamo valorizzare le proprietà DataTemplate del nostro SampleTemplateSelector nel markup tutte come StaticResource.

<Page.Resources>
    <DataTemplate x:Key="TP1">
        <TextBlock Text="{Binding Name}"
                    FontSize="20"
                    Foreground="Green" />
    </DataTemplate>

    <DataTemplate x:Key="TP2">
        <TextBlock Text="{Binding Name}"
                    FontSize="20"
                    Foreground="Red" />
    </DataTemplate>
        
    <DataTemplate x:Key="TP3">
        <TextBlock Text="{Binding Name}"
                    FontSize="40"
                    FontStyle="Italic"
                    Foreground="GreenYellow" />
    </DataTemplate>

    <local:SampleTemplateSelector x:Key="SampleTemplateSelector"
                                    Template1="{StaticResource TP1}"
                                    Template2="{StaticResource TP2}"
                                    Template3="{StaticResource TP3}"/>
</Page.Resources>

<Grid Margin="120,100,0,0">
    <ItemsControl ItemsSource="{Binding Source={StaticResource groupedItemsViewSource}}"
                  ItemTemplateSelector="{StaticResource SampleTemplateSelector}">
....

In questo modo il tutto è flessibile e ben gestibile anche a design time.

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

I più letti di oggi