Partager via


Création d’un Xamarin.Forms DataTemplate

Les modèles de données peuvent être créés inline, dans un ResourceDictionary, ou à partir d’un type personnalisé ou d’un type de cellule approprié Xamarin.Forms . Cet article explore chaque technique.

Pour DataTemplate, le scénario d’usage courant consiste à afficher des données provenant d’une collection d’objets dans un ListView. Vous pouvez gérer l’apparence des données de chaque cellule dans ListView en affectant à la propriété ListView.ItemTemplate un DataTemplate. Plusieurs techniques permettent d’y parvenir :

Quelle que soit la technique utilisée, l’apparence de chaque cellule du ListView est définie par un DataTemplate, comme indiqué dans les captures d’écran suivantes :

ListView avec un DataTemplate

Création d’un DataTemplate inline

Vous pouvez affecter à la propriété ListView.ItemTemplate un DataTemplate inline. Vous devez utiliser un modèle inline, c’est-à-dire un modèle placé en tant qu’enfant direct d’une propriété de contrôle appropriée, s’il n’est pas nécessaire de réutiliser le modèle de données ailleurs. Les éléments spécifiés dans DataTemplate définissent l’apparence de chaque cellule, comme indiqué dans l’exemple de code XAML suivant :

<ListView Margin="0,20,0,0">
    <ListView.ItemsSource>
        <x:Array Type="{x:Type local:Person}">
            <local:Person Name="Steve" Age="21" Location="USA" />
            <local:Person Name="John" Age="37" Location="USA" />
            <local:Person Name="Tom" Age="42" Location="UK" />
            <local:Person Name="Lucas" Age="29" Location="Germany" />
            <local:Person Name="Tariq" Age="39" Location="UK" />
            <local:Person Name="Jane" Age="30" Location="USA" />
        </x:Array>
    </ListView.ItemsSource>
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <Grid>
                    ...
                    <Label Text="{Binding Name}" FontAttributes="Bold" />
                    <Label Grid.Column="1" Text="{Binding Age}" />
                    <Label Grid.Column="2" Text="{Binding Location}" HorizontalTextAlignment="End" />
                </Grid>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

L’enfant d’un DataTemplate inline doit être de type Cell ou en dériver. Cet exemple utilise un ViewCell, qui dérive de Cell. La disposition dans ViewCell est gérée ici par Grid. Grid contient trois instances de Label qui lient leurs propriétés Text aux propriétés appropriées de chaque objet Person de la collection.

Le code C# équivalent est affiché dans l’exemple de code suivant :

public class WithDataTemplatePageCS : ContentPage
{
    public WithDataTemplatePageCS()
    {
        ...
        var people = new List<Person>
        {
            new Person { Name = "Steve", Age = 21, Location = "USA" },
            ...
        };

        var personDataTemplate = new DataTemplate(() =>
        {
            var grid = new Grid();
            ...
            var nameLabel = new Label { FontAttributes = FontAttributes.Bold };
            var ageLabel = new Label();
            var locationLabel = new Label { HorizontalTextAlignment = TextAlignment.End };

            nameLabel.SetBinding(Label.TextProperty, "Name");
            ageLabel.SetBinding(Label.TextProperty, "Age");
            locationLabel.SetBinding(Label.TextProperty, "Location");

            grid.Children.Add(nameLabel);
            grid.Children.Add(ageLabel, 1, 0);
            grid.Children.Add(locationLabel, 2, 0);

            return new ViewCell { View = grid };
        });

        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Children = {
                ...
                new ListView { ItemsSource = people, ItemTemplate = personDataTemplate, Margin = new Thickness(0, 20, 0, 0) }
            }
        };
    }
}

En C#, le DataTemplate inline est créé à l’aide d’une surcharge de constructeur qui spécifie un argument Func.

Création d’un DataTemplate avec un type

Vous pouvez également affecter à la propriété ListView.ItemTemplate un DataTemplate créé à partir d’un type de cellule. L’avantage de cette approche est que l’apparence définie par le type de cellule peut être réutilisée par plusieurs modèles de données dans l’application. Le code XAML suivant montre un exemple de cette approche :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataTemplates"
             ...>
    <StackLayout Margin="20">
        ...
        <ListView Margin="0,20,0,0">
           <ListView.ItemsSource>
                <x:Array Type="{x:Type local:Person}">
                    <local:Person Name="Steve" Age="21" Location="USA" />
                    ...
                </x:Array>
            </ListView.ItemsSource>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <local:PersonCell />
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

Ici, la propriété ListView.ItemTemplate a la valeur d’un DataTemplate créé à partir d’un type personnalisé qui définit l’apparence de la cellule. Le type personnalisé doit dériver du type ViewCell, comme indiqué dans l’exemple de code suivant :

<ViewCell xmlns="http://xamarin.com/schemas/2014/forms"
          xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
          x:Class="DataTemplates.PersonCell">
     <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.5*" />
            <ColumnDefinition Width="0.2*" />
            <ColumnDefinition Width="0.3*" />
        </Grid.ColumnDefinitions>
        <Label Text="{Binding Name}" FontAttributes="Bold" />
        <Label Grid.Column="1" Text="{Binding Age}" />
        <Label Grid.Column="2" Text="{Binding Location}" HorizontalTextAlignment="End" />
    </Grid>
</ViewCell>

Dans ViewCell, la disposition est gérée ici par Grid. Grid contient trois instances de Label qui lient leurs propriétés Text aux propriétés appropriées de chaque objet Person de la collection.

Le code C# équivalent est indiqué dans l’exemple suivant :

public class WithDataTemplatePageFromTypeCS : ContentPage
{
    public WithDataTemplatePageFromTypeCS()
    {
        ...
        var people = new List<Person>
        {
            new Person { Name = "Steve", Age = 21, Location = "USA" },
            ...
        };

        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Children = {
                ...
                new ListView { ItemTemplate = new DataTemplate(typeof(PersonCellCS)), ItemsSource = people, Margin = new Thickness(0, 20, 0, 0) }
            }
        };
    }
}

En C#, le DataTemplate est créé à l’aide d’une surcharge de constructeur qui spécifie le type de cellule en tant qu’argument. Le type de cellule doit dériver du type ViewCell, comme indiqué dans l’exemple de code suivant :

public class PersonCellCS : ViewCell
{
    public PersonCellCS()
    {
        var grid = new Grid();
        ...
        var nameLabel = new Label { FontAttributes = FontAttributes.Bold };
        var ageLabel = new Label();
        var locationLabel = new Label { HorizontalTextAlignment = TextAlignment.End };

        nameLabel.SetBinding(Label.TextProperty, "Name");
        ageLabel.SetBinding(Label.TextProperty, "Age");
        locationLabel.SetBinding(Label.TextProperty, "Location");

        grid.Children.Add(nameLabel);
        grid.Children.Add(ageLabel, 1, 0);
        grid.Children.Add(locationLabel, 2, 0);

        View = grid;
    }
}

Remarque

Notez que Xamarin.Forms cela inclut également les types de cellules qui peuvent être utilisés pour afficher des données simples dans les ListView cellules. Pour plus d’informations, consultez Apparence de cellule.

Création d’un DataTemplate en tant que ressource

Vous pouvez également créer des modèles de données sous forme d’objets réutilisables dans un ResourceDictionary. Pour ce faire, vous affectez à chaque déclaration un attribut x:Key unique, qui lui fournit une clé descriptive dans ResourceDictionary, comme indiqué dans l’exemple de code XAML suivant :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             ...>
    <ContentPage.Resources>
        <ResourceDictionary>
            <DataTemplate x:Key="personTemplate">
                 <ViewCell>
                    <Grid>
                        ...
                    </Grid>
                </ViewCell>
            </DataTemplate>
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout Margin="20">
        ...
        <ListView ItemTemplate="{StaticResource personTemplate}" Margin="0,20,0,0">
            <ListView.ItemsSource>
                <x:Array Type="{x:Type local:Person}">
                    <local:Person Name="Steve" Age="21" Location="USA" />
                    ...
                </x:Array>
            </ListView.ItemsSource>
        </ListView>
    </StackLayout>
</ContentPage>

DataTemplate est affecté à la propriété ListView.ItemTemplate à l’aide de l’extension de balisage StaticResource. Notez que même si DataTemplate est défini dans le ResourceDictionary de la page, il peut également l’être au niveau du contrôle ou de l’application.

L’exemple de code suivant montre la page équivalente en C# :

public class WithDataTemplatePageCS : ContentPage
{
  public WithDataTemplatePageCS ()
  {
    ...
    var personDataTemplate = new DataTemplate (() => {
      var grid = new Grid ();
      ...
      return new ViewCell { View = grid };
    });

    Resources = new ResourceDictionary ();
    Resources.Add ("personTemplate", personDataTemplate);

    Content = new StackLayout {
      Margin = new Thickness(20),
      Children = {
        ...
        new ListView { ItemTemplate = (DataTemplate)Resources ["personTemplate"], ItemsSource = people };
      }
    };
  }
}

DataTemplate est ajouté au ResourceDictionary à l’aide de la méthode Add, qui spécifie une chaîne Key permettant de référencer DataTemplate durant sa récupération.

Résumé

Cet article explique comment créer des modèles de données inline à partir d’un type personnalisé ou dans un ResourceDictionary. Vous devez utiliser un modèle inline si vous n’avez pas besoin de réutiliser le modèle de données ailleurs. Vous pouvez aussi réutiliser un modèle de données en le définissant comme un type personnalisé, ou comme une ressource au niveau du contrôle, de la page ou de l’application.