Criando um :::no-loc(Xamarin.Forms)::: DataTemplateSelectorCreating a :::no-loc(Xamarin.Forms)::: DataTemplateSelector

Baixar Exemplo Baixar o exemploDownload Sample Download the sample

Um DataTemplateSelector pode ser usado para escolher um DataTemplate em tempo de execução com base no valor de uma propriedade associada a dados. Isso permite que vários DataTemplates sejam aplicados ao mesmo tipo de objeto, para personalizar a aparência de objetos específicos. Este artigo demonstra como criar e consumir um DataTemplateSelector.A DataTemplateSelector can be used to choose a DataTemplate at runtime based on the value of a data-bound property. This enables multiple DataTemplates to be applied to the same type of object, to customize the appearance of particular objects. This article demonstrates how to create and consume a DataTemplateSelector.

Um seletor de modelo de dados permite cenários como uma ListView associação a uma coleção de objetos, em que a aparência de cada objeto no ListView pode ser escolhida em tempo de execução pelo seletor de modelo de dados que retorna um determinado DataTemplate .A data template selector enables scenarios such as a ListView binding to a collection of objects, where the appearance of each object in the ListView can be chosen at runtime by the data template selector returning a particular DataTemplate.

Criando um DataTemplateSelectorCreating a DataTemplateSelector

Um seletor de modelo de dados é implementado pela criação de uma classe herdada de DataTemplateSelector .A data template selector is implemented by creating a class that inherits from DataTemplateSelector. O OnSelectTemplate método é então substituído para retornar um específico DataTemplate , conforme mostrado no exemplo de código a seguir:The OnSelectTemplate method is then overridden to return a particular DataTemplate, as shown in the following code example:

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;
  }
}

O método OnSelectTemplate retorna o modelo apropriado com base no valor da propriedade DateOfBirth.The OnSelectTemplate method returns the appropriate template based on the value of the DateOfBirth property. O modelo a ser retornado é o valor da propriedade ValidTemplate ou da propriedade InvalidTemplate, que são definidas ao consumir o PersonDataTemplateSelector.The template to return is the value of the ValidTemplate property or the InvalidTemplate property, which are set when consuming the PersonDataTemplateSelector.

Uma instância da classe de seletor de modelo de dados pode ser atribuída a :::no-loc(Xamarin.Forms)::: Propriedades de controle, como ListView.ItemTemplate .An instance of the data template selector class can then be assigned to :::no-loc(Xamarin.Forms)::: control properties such as ListView.ItemTemplate. Para obter uma lista de propriedades válidas, confira Criando um DataTemplate.For a list of valid properties, see Creating a DataTemplate.

LimitaçõesLimitations

DataTemplateSelector as instâncias têm as seguintes limitações:DataTemplateSelector instances have the following limitations:

  • A subclasse DataTemplateSelector deve sempre retornar o mesmo modelo para os mesmos dados se consultada várias vezes.The DataTemplateSelector subclass must always return the same template for the same data if queried multiple times.
  • A subclasse DataTemplateSelector não deve retornar outra subclasse DataTemplateSelector.The DataTemplateSelector subclass must not return another DataTemplateSelector subclass.
  • A subclasse DataTemplateSelector não deve retornar novas instâncias de um DataTemplate em cada chamada.The DataTemplateSelector subclass must not return new instances of a DataTemplate on each call. Em vez disso, a mesma instância deve ser retornada.Instead, the same instance must be returned. Não fazer isso criará uma perda de memória e desabilitará a virtualização.Failure to do so will create a memory leak and will disable virtualization.
  • No Android, não pode haver mais de 20 modelos de dados diferentes por ListView.On Android, there can be no more than 20 different data templates per ListView.

Consumindo um DataTemplateSelector em XAMLConsuming a DataTemplateSelector in XAML

Em XAML, o PersonDataTemplateSelector pode ser instanciado ao declará-lo como um recurso, conforme mostrado no exemplo de código a seguir:In XAML, the PersonDataTemplateSelector can be instantiated by declaring it as a resource, as shown in the following code example:

<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>

Esse nível ResourceDictionary de página define duas DataTemplate instâncias e uma PersonDataTemplateSelector instância.This page level ResourceDictionary defines two DataTemplate instances and a PersonDataTemplateSelector instance. A instância PersonDataTemplateSelector define suas propriedades ValidTemplate e InvalidTemplate como as instâncias DataTemplate apropriadas usando a extensão de marcação StaticResource.The PersonDataTemplateSelector instance sets its ValidTemplate and InvalidTemplate properties to the appropriate DataTemplate instances by using the StaticResource markup extension. Observe que, embora os recursos sejam definidos na página ResourceDictionary , eles também podem ser definidos no nível de controle ou do aplicativo.Note that while the resources are defined in the page's ResourceDictionary, they could also be defined at the control level or application level.

A PersonDataTemplateSelector instância é consumida atribuindo-a à ListView.ItemTemplate propriedade, conforme mostrado no exemplo de código a seguir:The PersonDataTemplateSelector instance is consumed by assigning it to the ListView.ItemTemplate property, as shown in the following code example:

<ListView x:Name="listView" ItemTemplate="{StaticResource personDataTemplateSelector}" />

Em tempo de execução, o ListView chama o PersonDataTemplateSelector.OnSelectTemplate método para cada um dos itens na coleção subjacente, com a chamada passando o objeto de dados como o item parâmetro.At runtime, the ListView calls the PersonDataTemplateSelector.OnSelectTemplate method for each of the items in the underlying collection, with the call passing the data object as the item parameter. O DataTemplate que é retornado pelo método é então aplicado a esse objeto.The DataTemplate that is returned by the method is then applied to that object.

As capturas de tela a seguir mostram o resultado da ListView aplicação do PersonDataTemplateSelector para cada objeto na coleção subjacente:The following screenshots show the result of the ListView applying the PersonDataTemplateSelector to each object in the underlying collection:

ListView com um Seletor de Modelo de Dados

Qualquer objeto Person que tem o valor da propriedade DateOfBirth maior que ou igual a 1980 é exibido em verde, com os objetos restantes sendo exibidos em vermelho.Any Person object that has a DateOfBirth property value greater than or equal to 1980 is displayed in green, with the remaining objects being displayed in red.

Consumindo um DataTemplateSelector em C#Consuming a DataTemplateSelector in C#

No C#, o PersonDataTemplateSelector pode ser instanciado e atribuído à ListView.ItemTemplate propriedade, conforme mostrado no exemplo de código a seguir:In C#, the PersonDataTemplateSelector can be instantiated and assigned to the ListView.ItemTemplate property, as shown in the following code example:

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
      }
    };
  }
  ...  
}

A PersonDataTemplateSelector instância define suas ValidTemplate InvalidTemplate Propriedades e para as DataTemplate instâncias apropriadas criadas pelo SetupDataTemplates método.The PersonDataTemplateSelector instance sets its ValidTemplate and InvalidTemplate properties to the appropriate DataTemplate instances created by the SetupDataTemplates method. Em tempo de execução, o ListView chama o PersonDataTemplateSelector.OnSelectTemplate método para cada um dos itens na coleção subjacente, com a chamada passando o objeto de dados como o item parâmetro.At runtime, the ListView calls the PersonDataTemplateSelector.OnSelectTemplate method for each of the items in the underlying collection, with the call passing the data object as the item parameter. O DataTemplate retornado pelo método é aplicado a esse objeto.The DataTemplate that is returned by the method is then applied to that object.

ResumoSummary

Este artigo demonstrou como criar e consumir um DataTemplateSelector .This article has demonstrated how to create and consume a DataTemplateSelector. Um DataTemplateSelector pode ser usado para escolher um DataTemplate em tempo de execução com base no valor de uma propriedade associada a dados.A DataTemplateSelector can be used to choose a DataTemplate at runtime based on the value of a data-bound property. Isso permite que várias instâncias de DataTemplate sejam aplicadas ao mesmo tipo de objeto, para personalizar a aparência de objetos específicos.This enables multiple DataTemplate instances to be applied to the same type of object, to customize the appearance of particular objects.