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 :
- Création d’un DataTemplate inline.
- Création d’un DataTemplate avec un type.
- Création d’un DataTemplate en tant que ressource.
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 :
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.