Personnalisation d’une ViewCell
Un Xamarin.Forms ViewCell est une cellule qui peut être ajoutée à une vue ListView ou TableView, qui contient une vue définie par le développeur. Cet article montre comment créer un renderer personnalisé pour un ViewCell hébergé à l’intérieur d’un Xamarin.Forms contrôle ListView. Cela empêche les Xamarin.Forms calculs de disposition d’être appelés à plusieurs reprises pendant le défilement ListView.
Chaque Xamarin.Forms cellule a un renderer associé pour chaque plateforme qui crée une instance d’un contrôle natif. Lorsqu’une ViewCell
application est rendue Xamarin.Forms , dans iOS, la ViewCellRenderer
classe est instanciée, ce qui instancie à son tour un contrôle natif UITableViewCell
. Sur la plateforme Android, la classe ViewCellRenderer
instancie un contrôle View
natif. Sur la plateforme Windows universelle (UWP), la classe ViewCellRenderer
instancie un DataTemplate
natif. Pour plus d’informations sur les classes de renderer et de contrôle natives qui contrôlent Xamarin.Forms la correspondance, consultez Les classes de base du renderer et les contrôles natifs.
Le diagramme suivant illustre la relation entre ViewCell
et les contrôles natifs correspondants qui l’implémentent :
Vous pouvez tirer profit du processus de rendu pour implémenter des personnalisations spécifiques à la plateforme en créant un renderer personnalisé pour un ViewCell
sur chaque plateforme. Le processus pour y parvenir est le suivant :
- Créez une Xamarin.Forms cellule personnalisée.
- Consommez la cellule personnalisée à partir de Xamarin.Forms.
- Créez le renderer personnalisé pour la cellule sur chaque plateforme.
Chaque élément sera maintenant abordé à son tour pour implémenter un NativeCell
renderer qui tire parti d’une disposition spécifique à la plateforme pour chaque cellule hébergée à l’intérieur d’un Xamarin.FormsListView
contrôle. Cela empêche les Xamarin.Forms calculs de disposition d’être appelés à plusieurs reprises pendant ListView
le défilement.
Création de la cellule personnalisée
Un contrôle de cellule personnalisé peut être créé à l’aide d’une sous-classe de la classe ViewCell
, comme indiqué dans l’exemple de code suivant :
public class NativeCell : ViewCell
{
public static readonly BindableProperty NameProperty =
BindableProperty.Create ("Name", typeof(string), typeof(NativeCell), "");
public string Name {
get { return (string)GetValue (NameProperty); }
set { SetValue (NameProperty, value); }
}
public static readonly BindableProperty CategoryProperty =
BindableProperty.Create ("Category", typeof(string), typeof(NativeCell), "");
public string Category {
get { return (string)GetValue (CategoryProperty); }
set { SetValue (CategoryProperty, value); }
}
public static readonly BindableProperty ImageFilenameProperty =
BindableProperty.Create ("ImageFilename", typeof(string), typeof(NativeCell), "");
public string ImageFilename {
get { return (string)GetValue (ImageFilenameProperty); }
set { SetValue (ImageFilenameProperty, value); }
}
}
La classe NativeCell
est créée dans le projet de bibliothèque .NET Standard et définit l’API pour la cellule personnalisée. La cellule personnalisée expose les propriétés Name
, Category
et ImageFilename
qui peuvent être affichées par le biais de la liaison de données. Pour plus d’informations sur la liaison de données, consultez Notions de base de la liaison de données.
Consommation de la cellule personnalisée
Vous pouvez référencer la cellule personnalisée NativeCell
en Xaml dans le projet de bibliothèque .NET Standard en déclarant un espace de noms pour son emplacement et en utilisant le préfixe d’espace de noms sur l’élément de cellule personnalisée. L’exemple de code suivant montre comment la cellule personnalisée NativeCell
peut être consommée par une page XAML :
<ContentPage ...
xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
...>
...
<ContentPage.Content>
<StackLayout>
<Label Text="Xamarin.Forms native cell" HorizontalTextAlignment="Center" />
<ListView x:Name="listView" CachingStrategy="RecycleElement" ItemSelected="OnItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<local:NativeCell Name="{Binding Name}" Category="{Binding Category}" ImageFilename="{Binding ImageFilename}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Le préfixe d’espace de noms local
peut porter n’importe quel nom. Toutefois, les valeurs clr-namespace
et assembly
doivent correspondre aux détails du contrôle personnalisé. Une fois l’espace de noms déclaré, le préfixe est utilisé pour référencer la cellule personnalisée.
L’exemple de code suivant montre comment la cellule personnalisée NativeCell
peut être consommé par une page C# :
public class NativeCellPageCS : ContentPage
{
ListView listView;
public NativeCellPageCS()
{
listView = new ListView(ListViewCachingStrategy.RecycleElement)
{
ItemsSource = DataSource.GetList(),
ItemTemplate = new DataTemplate(() =>
{
var nativeCell = new NativeCell();
nativeCell.SetBinding(NativeCell.NameProperty, "Name");
nativeCell.SetBinding(NativeCell.CategoryProperty, "Category");
nativeCell.SetBinding(NativeCell.ImageFilenameProperty, "ImageFilename");
return nativeCell;
})
};
switch (Device.RuntimePlatform)
{
case Device.iOS:
Padding = new Thickness(0, 20, 0, 0);
break;
case Device.Android:
case Device.UWP:
Padding = new Thickness(0);
break;
}
Content = new StackLayout
{
Children = {
new Label { Text = "Xamarin.Forms native cell", HorizontalTextAlignment = TextAlignment.Center },
listView
}
};
listView.ItemSelected += OnItemSelected;
}
...
}
Un Xamarin.FormsListView
contrôle est utilisé pour afficher une liste de données, qui est remplie par le biais de la ItemSource
propriété. La stratégie de mise en cache RecycleElement
tente de réduire la vitesse d’exécution et l’empreinte mémoire de ListView
en recyclant les cellules de la liste. Pour plus d’informations, consultez Stratégie de mise en cache.
Chaque ligne dans la liste contient trois éléments de données : un nom, une catégorie et un nom de fichier image. La disposition de chaque ligne dans la liste est définie par le DataTemplate
qui est référencé par le biais de la propriété ListView.ItemTemplate
pouvant être liée. Le DataTemplate
définit que chaque ligne de données dans la liste est un NativeCell
qui affiche ses propriétés Name
, Category
et ImageFilename
par le biais de la liaison de données. Pour plus d’informations sur le contrôle ListView
, consultez ListView.
Un renderer personnalisé peut maintenant être ajouté à chaque projet d’application afin de personnaliser la disposition spécifique à la plateforme pour chaque cellule.
Création du renderer personnalisé sur chaque plateforme
Le processus de création de la classe de renderer personnalisé est le suivant :
- Créez une sous-classe de la classe
ViewCellRenderer
qui affiche la cellule personnalisée. - Remplacez la méthode spécifique à la plateforme qui affiche le contrôle personnalisé et écrivez la logique pour le personnaliser.
- Ajoutez un
ExportRenderer
attribut à la classe de renderer personnalisée pour spécifier qu’il sera utilisé pour afficher la Xamarin.Forms cellule personnalisée. Cet attribut est utilisé pour inscrire le renderer personnalisé avec Xamarin.Forms.
Remarque
Pour la plupart des Xamarin.Forms éléments, il est facultatif de fournir un renderer personnalisé dans chaque projet de plateforme. Si un renderer personnalisé n’est pas inscrit, le renderer par défaut de la classe de base du contrôle est utilisé. Toutefois, les renderers personnalisés sont nécessaires dans chaque projet de plateforme durant la restitution d’un élément ViewCell.
Le diagramme suivant illustre les responsabilités de chaque projet dans l’exemple d’application ainsi que les relations qu’ils entretiennent les uns avec les autres :
La cellule personnalisée NativeCell
est restituée par des classes de renderer spécifiques à la plateforme qui dérivent toutes de la classe ViewCellRenderer
pour chaque plateforme. Il en résulte la restitution de chaque cellule personnalisée NativeCell
avec une disposition spécifique à la plateforme, comme le montrent les captures d’écran suivantes :
La classe ViewCellRenderer
expose des méthodes spécifiques à la plateforme pour le rendu de la cellule personnalisée. Il s’agit de la méthode GetCell
sur la plateforme iOS, de la méthode GetCellCore
sur la plateforme Android et de la méthode GetTemplate
sur UWP.
Chaque classe de renderer personnalisée est décorée avec un ExportRenderer
attribut qui inscrit le renderer avec Xamarin.Forms. L’attribut prend deux paramètres : le nom de type de la Xamarin.Forms cellule affichée et le nom de type du renderer personnalisé. Le préfixe assembly
de l’attribut spécifie que l’attribut s’applique à la totalité de l’assembly.
Les sections suivantes décrivent l’implémentation de chaque classe de renderer personnalisé spécifique à la plateforme.
Création du renderer personnalisé sur iOS
L’exemple de code suivant illustre le renderer personnalisé pour la plateforme iOS :
[assembly: ExportRenderer(typeof(NativeCell), typeof(NativeiOSCellRenderer))]
namespace CustomRenderer.iOS
{
public class NativeiOSCellRenderer : ViewCellRenderer
{
NativeiOSCell cell;
public override UITableViewCell GetCell(Cell item, UITableViewCell reusableCell, UITableView tv)
{
var nativeCell = (NativeCell)item;
cell = reusableCell as NativeiOSCell;
if (cell == null)
cell = new NativeiOSCell(item.GetType().FullName, nativeCell);
else
cell.NativeCell.PropertyChanged -= OnNativeCellPropertyChanged;
nativeCell.PropertyChanged += OnNativeCellPropertyChanged;
cell.UpdateCell(nativeCell);
return cell;
}
...
}
}
La méthode GetCell
est appelée pour générer chaque cellule à afficher. Chaque cellule est une instance NativeiOSCell
, qui définit la disposition de la cellule et de ses données. L’opération de la méthode GetCell
dépend de la stratégie de mise en cache ListView
:
Quand la stratégie de mise en cache
ListView
estRetainElement
, la méthodeGetCell
est appelée pour chaque cellule. Une instanceNativeiOSCell
est créée pour chaque instanceNativeCell
initialement affichée sur l’écran. Quand l’utilisateur fait défiler laListView
, les instancesNativeiOSCell
sont réutilisées. Pour plus d’informations sur la réutilisation de cellules iOS, consultez Réutilisation de cellule.Remarque
Ce code de renderer personnalisé effectue une réutilisation de cellule même quand la
ListView
est définie pour conserver les cellules.Les données affichées par chaque instance
NativeiOSCell
, qu’elle soit créée ou réutilisée, sont actualisées avec les données de chaque instanceNativeCell
par la méthodeUpdateCell
.Remarque
La méthode
OnNativeCellPropertyChanged
n’est jamais appelée quand la stratégie de mise en cacheListView
est définie pour conserver les cellules.Quand la stratégie de mise en cache
ListView
estRecycleElement
, la méthodeGetCell
est appelée pour chaque cellule initialement affichée sur l’écran. Une instanceNativeiOSCell
est créée pour chaque instanceNativeCell
initialement affichée sur l’écran. Les données affichées par chaque instanceNativeiOSCell
sont actualisées avec les données de l’instanceNativeCell
par la méthodeUpdateCell
. Toutefois, la méthodeGetCell
n’est pas appelée quand l’utilisateur fait défiler laListView
. Au lieu de cela, les instancesNativeiOSCell
sont réutilisées. Des événementsPropertyChanged
sont déclenchés sur l’instanceNativeCell
quand ses données changent, et le gestionnaire d’événementsOnNativeCellPropertyChanged
met à jour les données dans chaque instanceNativeiOSCell
réutilisée.
L’exemple de code suivant montre la méthode OnNativeCellPropertyChanged
qui est appelée quand un événement PropertyChanged
est déclenché :
namespace CustomRenderer.iOS
{
public class NativeiOSCellRenderer : ViewCellRenderer
{
...
void OnNativeCellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var nativeCell = (NativeCell)sender;
if (e.PropertyName == NativeCell.NameProperty.PropertyName)
{
cell.HeadingLabel.Text = nativeCell.Name;
}
else if (e.PropertyName == NativeCell.CategoryProperty.PropertyName)
{
cell.SubheadingLabel.Text = nativeCell.Category;
}
else if (e.PropertyName == NativeCell.ImageFilenameProperty.PropertyName)
{
cell.CellImageView.Image = cell.GetImage(nativeCell.ImageFilename);
}
}
}
}
Cette méthode met à jour les données affichées par des instances NativeiOSCell
réutilisées. La méthode pouvant être appelée plusieurs fois, la propriété qui est changée fait l’objet d’une recherche.
La classe NativeiOSCell
définit la disposition pour chaque cellule et est illustrée dans l’exemple de code suivant :
internal class NativeiOSCell : UITableViewCell, INativeElementView
{
public UILabel HeadingLabel { get; set; }
public UILabel SubheadingLabel { get; set; }
public UIImageView CellImageView { get; set; }
public NativeCell NativeCell { get; private set; }
public Element Element => NativeCell;
public NativeiOSCell(string cellId, NativeCell cell) : base(UITableViewCellStyle.Default, cellId)
{
NativeCell = cell;
SelectionStyle = UITableViewCellSelectionStyle.Gray;
ContentView.BackgroundColor = UIColor.FromRGB(255, 255, 224);
CellImageView = new UIImageView();
HeadingLabel = new UILabel()
{
Font = UIFont.FromName("Cochin-BoldItalic", 22f),
TextColor = UIColor.FromRGB(127, 51, 0),
BackgroundColor = UIColor.Clear
};
SubheadingLabel = new UILabel()
{
Font = UIFont.FromName("AmericanTypewriter", 12f),
TextColor = UIColor.FromRGB(38, 127, 0),
TextAlignment = UITextAlignment.Center,
BackgroundColor = UIColor.Clear
};
ContentView.Add(HeadingLabel);
ContentView.Add(SubheadingLabel);
ContentView.Add(CellImageView);
}
public void UpdateCell(NativeCell cell)
{
HeadingLabel.Text = cell.Name;
SubheadingLabel.Text = cell.Category;
CellImageView.Image = GetImage(cell.ImageFilename);
}
public UIImage GetImage(string filename)
{
return (!string.IsNullOrWhiteSpace(filename)) ? UIImage.FromFile("Images/" + filename + ".jpg") : null;
}
public override void LayoutSubviews()
{
base.LayoutSubviews();
HeadingLabel.Frame = new CGRect(5, 4, ContentView.Bounds.Width - 63, 25);
SubheadingLabel.Frame = new CGRect(100, 18, 100, 20);
CellImageView.Frame = new CGRect(ContentView.Bounds.Width - 63, 5, 33, 33);
}
}
Cette classe définit les contrôles permettant de restituer le contenu de la cellule et sa disposition. La classe implémente l’interface INativeElementView
, nécessaire quand la ListView
utilise la stratégie de mise en cache RecycleElement
. Cette interface spécifie que la classe doit implémenter la propriété Element
, qui doit retourner les données de cellule personnalisée pour les cellules recyclées.
Le constructeur NativeiOSCell
initialise l’apparence des propriétés HeadingLabel
, SubheadingLabel
et CellImageView
. Ces propriétés sont utilisées pour afficher les données stockées dans l’instance NativeCell
, la méthode UpdateCell
étant appelée pour définir la valeur de chaque propriété. En outre, quand la ListView
utilise la stratégie de mise en cache RecycleElement
, les données affichées par les propriétés HeadingLabel
, SubheadingLabel
et CellImageView
peuvent être mises à jour par la méthode OnNativeCellPropertyChanged
dans le renderer personnalisé.
La disposition des cellules est effectuée par le remplacement de LayoutSubviews
, qui définit les coordonnées de HeadingLabel
, SubheadingLabel
et CellImageView
au sein de la cellule.
Création du renderer personnalisé sur Android
L’exemple de code suivant illustre le renderer personnalisé pour la plateforme Android :
[assembly: ExportRenderer(typeof(NativeCell), typeof(NativeAndroidCellRenderer))]
namespace CustomRenderer.Droid
{
public class NativeAndroidCellRenderer : ViewCellRenderer
{
NativeAndroidCell cell;
protected override Android.Views.View GetCellCore(Cell item, Android.Views.View convertView, ViewGroup parent, Context context)
{
var nativeCell = (NativeCell)item;
Console.WriteLine("\t\t" + nativeCell.Name);
cell = convertView as NativeAndroidCell;
if (cell == null)
{
cell = new NativeAndroidCell(context, nativeCell);
}
else
{
cell.NativeCell.PropertyChanged -= OnNativeCellPropertyChanged;
}
nativeCell.PropertyChanged += OnNativeCellPropertyChanged;
cell.UpdateCell(nativeCell);
return cell;
}
...
}
}
La méthode GetCellCore
est appelée pour générer chaque cellule à afficher. Chaque cellule est une instance NativeAndroidCell
, qui définit la disposition de la cellule et de ses données. L’opération de la méthode GetCellCore
dépend de la stratégie de mise en cache ListView
:
Quand la stratégie de mise en cache
ListView
estRetainElement
, la méthodeGetCellCore
est appelée pour chaque cellule. UneNativeAndroidCell
est créée pour chaque instanceNativeCell
initialement affichée sur l’écran. Quand l’utilisateur fait défiler laListView
, les instancesNativeAndroidCell
sont réutilisées. Pour plus d’informations sur la réutilisation de cellules Android, consultez Réutilisation de vues de ligne.Remarque
Notez que ce code de renderer personnalisé effectue une réutilisation de cellule même quand la
ListView
est définie pour conserver les cellules.Les données affichées par chaque instance
NativeAndroidCell
, qu’elle soit créée ou réutilisée, sont actualisées avec les données de chaque instanceNativeCell
par la méthodeUpdateCell
.Remarque
Bien que la méthode
OnNativeCellPropertyChanged
soit appelée quand laListView
est définie pour conserver les cellules, elle ne met pas à jour les valeurs de la propriétéNativeAndroidCell
.Quand la stratégie de mise en cache
ListView
estRecycleElement
, la méthodeGetCellCore
est appelée pour chaque cellule initialement affichée sur l’écran. Une instanceNativeAndroidCell
est créée pour chaque instanceNativeCell
initialement affichée sur l’écran. Les données affichées par chaque instanceNativeAndroidCell
sont actualisées avec les données de l’instanceNativeCell
par la méthodeUpdateCell
. Toutefois, la méthodeGetCellCore
n’est pas appelée quand l’utilisateur fait défiler laListView
. Au lieu de cela, les instancesNativeAndroidCell
sont réutilisées. Des événementsPropertyChanged
sont déclenchés sur l’instanceNativeCell
quand ses données changent, et le gestionnaire d’événementsOnNativeCellPropertyChanged
met à jour les données dans chaque instanceNativeAndroidCell
réutilisée.
L’exemple de code suivant montre la méthode OnNativeCellPropertyChanged
qui est appelée quand un événement PropertyChanged
est déclenché :
namespace CustomRenderer.Droid
{
public class NativeAndroidCellRenderer : ViewCellRenderer
{
...
void OnNativeCellPropertyChanged(object sender, PropertyChangedEventArgs e)
{
var nativeCell = (NativeCell)sender;
if (e.PropertyName == NativeCell.NameProperty.PropertyName)
{
cell.HeadingTextView.Text = nativeCell.Name;
}
else if (e.PropertyName == NativeCell.CategoryProperty.PropertyName)
{
cell.SubheadingTextView.Text = nativeCell.Category;
}
else if (e.PropertyName == NativeCell.ImageFilenameProperty.PropertyName)
{
cell.SetImage(nativeCell.ImageFilename);
}
}
}
}
Cette méthode met à jour les données affichées par des instances NativeAndroidCell
réutilisées. La méthode pouvant être appelée plusieurs fois, la propriété qui est changée fait l’objet d’une recherche.
La classe NativeAndroidCell
définit la disposition pour chaque cellule et est illustrée dans l’exemple de code suivant :
internal class NativeAndroidCell : LinearLayout, INativeElementView
{
public TextView HeadingTextView { get; set; }
public TextView SubheadingTextView { get; set; }
public ImageView ImageView { get; set; }
public NativeCell NativeCell { get; private set; }
public Element Element => NativeCell;
public NativeAndroidCell(Context context, NativeCell cell) : base(context)
{
NativeCell = cell;
var view = (context as Activity).LayoutInflater.Inflate(Resource.Layout.NativeAndroidCell, null);
HeadingTextView = view.FindViewById<TextView>(Resource.Id.HeadingText);
SubheadingTextView = view.FindViewById<TextView>(Resource.Id.SubheadingText);
ImageView = view.FindViewById<ImageView>(Resource.Id.Image);
AddView(view);
}
public void UpdateCell(NativeCell cell)
{
HeadingTextView.Text = cell.Name;
SubheadingTextView.Text = cell.Category;
// Dispose of the old image
if (ImageView.Drawable != null)
{
using (var image = ImageView.Drawable as BitmapDrawable)
{
if (image != null)
{
if (image.Bitmap != null)
{
image.Bitmap.Dispose();
}
}
}
}
SetImage(cell.ImageFilename);
}
public void SetImage(string filename)
{
if (!string.IsNullOrWhiteSpace(filename))
{
// Display new image
Context.Resources.GetBitmapAsync(filename).ContinueWith((t) =>
{
var bitmap = t.Result;
if (bitmap != null)
{
ImageView.SetImageBitmap(bitmap);
bitmap.Dispose();
}
}, TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
// Clear the image
ImageView.SetImageBitmap(null);
}
}
}
Cette classe définit les contrôles permettant de restituer le contenu de la cellule et sa disposition. La classe implémente l’interface INativeElementView
, nécessaire quand la ListView
utilise la stratégie de mise en cache RecycleElement
. Cette interface spécifie que la classe doit implémenter la propriété Element
, qui doit retourner les données de cellule personnalisée pour les cellules recyclées.
Le constructeur NativeAndroidCell
agrandit la disposition NativeAndroidCell
et initialise les propriétés HeadingTextView
, SubheadingTextView
et ImageView
sur les contrôles dans la disposition agrandie. Ces propriétés sont utilisées pour afficher les données stockées dans l’instance NativeCell
, la méthode UpdateCell
étant appelée pour définir la valeur de chaque propriété. En outre, quand la ListView
utilise la stratégie de mise en cache RecycleElement
, les données affichées par les propriétés HeadingTextView
, SubheadingTextView
et ImageView
peuvent être mises à jour par la méthode OnNativeCellPropertyChanged
dans le renderer personnalisé.
L’exemple de code suivant montre la définition de la disposition pour le fichier de disposition NativeAndroidCell.axml
:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:background="@drawable/CustomSelector">
<LinearLayout
android:id="@+id/Text"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dip">
<TextView
android:id="@+id/HeadingText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FF7F3300"
android:textSize="20dip"
android:textStyle="italic" />
<TextView
android:id="@+id/SubheadingText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14dip"
android:textColor="#FF267F00"
android:paddingLeft="100dip" />
</LinearLayout>
<ImageView
android:id="@+id/Image"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="5dp"
android:src="@drawable/icon"
android:layout_alignParentRight="true" />
</RelativeLayout>
Cette disposition spécifie que deux contrôles TextView
et un contrôle ImageView
sont utilisés pour afficher le contenu de la cellule. Les deux contrôles TextView
sont orientés verticalement dans un contrôle LinearLayout
, tandis que tous les contrôles sont contenus dans une RelativeLayout
.
Création du renderer personnalisé sur UWP
L’exemple de code suivant illustre le renderer personnalisé pour UWP :
[assembly: ExportRenderer(typeof(NativeCell), typeof(NativeUWPCellRenderer))]
namespace CustomRenderer.UWP
{
public class NativeUWPCellRenderer : ViewCellRenderer
{
public override Windows.UI.Xaml.DataTemplate GetTemplate(Cell cell)
{
return App.Current.Resources["ListViewItemTemplate"] as Windows.UI.Xaml.DataTemplate;
}
}
}
La méthode GetTemplate
est appelée pour retourner la cellule à restituer pour chaque ligne de données dans la liste. Elle crée un DataTemplate
pour chaque instance NativeCell
qui s’affiche sur l’écran, le DataTemplate
définissant l’apparence et le contenu de la cellule.
Le DataTemplate
est stocké dans le dictionnaire de ressources de niveau application et est illustré dans l’exemple de code suivant :
<DataTemplate x:Key="ListViewItemTemplate">
<Grid Background="LightYellow">
<Grid.Resources>
<local:ConcatImageExtensionConverter x:Name="ConcatImageExtensionConverter" />
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.40*" />
<ColumnDefinition Width="0.40*"/>
<ColumnDefinition Width="0.20*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.ColumnSpan="2" Foreground="#7F3300" FontStyle="Italic" FontSize="22" VerticalAlignment="Top" Text="{Binding Name}" />
<TextBlock Grid.RowSpan="2" Grid.Column="1" Foreground="#267F00" FontWeight="Bold" FontSize="12" VerticalAlignment="Bottom" Text="{Binding Category}" />
<Image Grid.RowSpan="2" Grid.Column="2" HorizontalAlignment="Left" VerticalAlignment="Center" Source="{Binding ImageFilename, Converter={StaticResource ConcatImageExtensionConverter}}" Width="50" Height="50" />
<Line Grid.Row="1" Grid.ColumnSpan="3" X1="0" X2="1" Margin="30,20,0,0" StrokeThickness="1" Stroke="LightGray" Stretch="Fill" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
DataTemplate
spécifie les contrôles permettant d’afficher le contenu de la cellule ainsi que leurs disposition et apparence. Deux contrôles TextBlock
et un contrôle Image
sont utilisés pour afficher le contenu de la cellule par le biais de la liaison de données. En outre, une instance de ConcatImageExtensionConverter
est utilisée pour concaténer l’extension de fichier .jpg
à chaque nom de fichier image. Ainsi, le contrôle Image
peut charger et restituer l’image quand sa propriété Source
est définie.
Résumé
Cet article a montré comment créer un renderer personnalisé pour un ViewCell
qui est hébergé à l’intérieur d’un Xamarin.FormsListView
contrôle. Cela empêche les Xamarin.Forms calculs de disposition d’être appelés à plusieurs reprises pendant ListView
le défilement.