Partager via


Remplir un CarouselView de données

Parcourez l’exemple. Parcourir l'exemple

Dans .NET MAUI (.NET Multi-Platform App UI), CarouselView inclut les propriétés suivantes qui définissent les données à afficher et leur apparence :

  • ItemsSource, de type IEnumerable, spécifie la collection d’éléments à afficher et a une valeur par défaut de null.
  • ItemTemplate, de type DataTemplate, spécifie le modèle à appliquer à chaque élément de la collection d’éléments à afficher.

Les propriétés s’appuient sur des objets BindableProperty, ce qui signifie qu’elles peuvent être les cibles de liaisons de données.

CarouselView définit une propriété ItemsUpdatingScrollMode qui représente le comportement de défilement de CarouselView lorsque de nouveaux éléments y sont ajoutés. Pour plus d’informations sur cette propriété, consultez Contrôler la position de défilement lorsque de nouveaux éléments sont ajoutés.

CarouselView prend en charge la virtualisation incrémentielle des données à mesure que l’utilisateur réalise un défilement. Pour plus d’informations, consultez Charger des données de manière incrémentielle.

Remplir un CarouselView de données

Vous pouvez remplir un CarouselView avec des données en définissant sa propriété ItemsSource sur n’importe quelle collection qui implémente IEnumerable. Par défaut, CarouselView affiche des éléments horizontalement.

Important

Si CarouselView doit être actualisé à mesure que des éléments sont ajoutés, supprimés ou modifiés dans la collection sous-jacente, cette dernière doit être une collection IEnumerable qui envoie des notifications de modification de propriété, par exemple ObservableCollection.

Vous pouvez remplir CarouselView avec des données en utilisant une liaison de données pour lier sa propriété ItemsSource à une collection IEnumerable. En XAML, utilisez pour ce faire l’extension de balisage Binding :

<CarouselView ItemsSource="{Binding Monkeys}" />

Le code C# équivalent est :

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Dans cet exemple, les données de la propriété ItemsSource sont liées à la propriété Monkeys du viewmodel connecté.

Remarque

Vous pouvez activer les liaisons compilées pour améliorer les performances de liaison de données dans les applications .NET MAUI. Pour plus d’informations, consultez Liaisons compilées.

Pour découvrir plus d’informations sur la modification d’orientation CarouselView, consultez Spécifier la disposition CarouselView. Pour plus d’informations sur la définition de l’apparence de chaque élément dans CarouselView, consultez Définir l’apparence d’un élément. Pour plus d’informations sur la liaison de données, consultez Liaison de données.

Définir l’apparence de l’élément

Vous pouvez définir l’apparence de chaque élément dans CarouselView en définissant la propriété CarouselView.ItemTemplate sur un DataTemplate :

<CarouselView ItemsSource="{Binding Monkeys}">
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                <Frame HasShadow="True"
                       BorderColor="DarkGray"
                       CornerRadius="5"
                       Margin="20"
                       HeightRequest="300"
                       HorizontalOptions="Center"
                       VerticalOptions="CenterAndExpand">
                    <StackLayout>
                        <Label Text="{Binding Name}"
                               FontAttributes="Bold"
                               FontSize="18"
                               HorizontalOptions="Center"
                               VerticalOptions="Center" />
                        <Image Source="{Binding ImageUrl}"
                               Aspect="AspectFill"
                               HeightRequest="150"
                               WidthRequest="150"
                               HorizontalOptions="Center" />
                        <Label Text="{Binding Location}"
                               HorizontalOptions="Center" />
                        <Label Text="{Binding Details}"
                               FontAttributes="Italic"
                               HorizontalOptions="Center"
                               MaxLines="5"
                               LineBreakMode="TailTruncation" />
                    </StackLayout>
                </Frame>
            </StackLayout>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>

Le code C# équivalent est :

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

carouselView.ItemTemplate = new DataTemplate(() =>
{
    Label nameLabel = new Label { ... };
    nameLabel.SetBinding(Label.TextProperty, "Name");

    Image image = new Image { ... };
    image.SetBinding(Image.SourceProperty, "ImageUrl");

    Label locationLabel = new Label { ... };
    locationLabel.SetBinding(Label.TextProperty, "Location");

    Label detailsLabel = new Label { ... };
    detailsLabel.SetBinding(Label.TextProperty, "Details");

    StackLayout stackLayout = new StackLayout();
    stackLayout.Add(nameLabel);
    stackLayout.Add(image);
    stackLayout.Add(locationLabel);
    stackLayout.Add(detailsLabel);

    Frame frame = new Frame { ... };
    StackLayout rootStackLayout = new StackLayout();
    rootStackLayout.Add(frame);

    return rootStackLayout;
});

Les éléments spécifiés dans le DataTemplate définissent l’apparence de chaque élément de CarouselView. Dans l’exemple, la disposition dans DataTemplate est gérée par une StackLayout et les données sont affichées avec un objet Image et trois objets Label qui sont tous liés aux propriétés de la classe Monkey :

public class Monkey
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

La capture d’écran suivante montre un exemple de création de modèles de chaque élément :

Capture d’écran d’un CarouselView où chaque élément est basé sur un modèle.

Pour plus d’informations sur les modèles de données, consultez Modèles de données.

Choisir l’apparence de l’élément au moment de l’exécution

Vous pouvez choisir l’apparence de chaque élément dans CarouselView au moment de l’exécution, en fonction de la valeur de l’élément, en définissant la propriété CarouselView.ItemTemplate sur un objet DataTemplateSelector :

<ContentPage ...
             xmlns:controls="clr-namespace:CarouselViewDemos.Controls"
             x:Class="CarouselViewDemos.Views.HorizontalLayoutDataTemplateSelectorPage">
    <ContentPage.Resources>
        <DataTemplate x:Key="AmericanMonkeyTemplate">
            ...
        </DataTemplate>

        <DataTemplate x:Key="OtherMonkeyTemplate">
            ...
        </DataTemplate>

        <controls:MonkeyDataTemplateSelector x:Key="MonkeySelector"
                                             AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
                                             OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
    </ContentPage.Resources>

    <CarouselView ItemsSource="{Binding Monkeys}"
                  ItemTemplate="{StaticResource MonkeySelector}" />
</ContentPage>

Le code C# équivalent est :

CarouselView carouselView = new CarouselView
{
    ItemTemplate = new MonkeyDataTemplateSelector { ... }
};
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

La propriété ItemTemplate est définie sur un objet MonkeyDataTemplateSelector. L’exemple suivant présente la classe MonkeyDataTemplateSelector :

public class MonkeyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate AmericanMonkey { get; set; }
    public DataTemplate OtherMonkey { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
    }
}

La classe MonkeyDataTemplateSelector définit les propriétés AmericanMonkey et OtherMonkey DataTemplate définies sur différents modèles de données. Le remplacement OnSelectTemplate retourne le modèle AmericanMonkey lorsque le nom du singe contient « America ». Si le nom du singe ne contient pas « America », le remplacement OnSelectTemplate retourne le modèle OtherMonkey qui affiche ses données grisées :

Capture d’écran de la sélection du modèle d’élément de runtime CarouselView.

Pour plus d’informations sur les sélecteurs de modèles de données, consultez Créer un DataTemplateSelector.

Important

Lorsque vous utilisez CarouselView, ne définissez jamais l’élément racine de vos objets DataTemplate sur ViewCell. Il en résulte la levée d’une exception, car CarouselView n’a aucun concept des cellules.

Indicateurs d’affichage

Les indicateurs, qui représentent le nombre d’éléments et la position actuelle dans un CarouselView, peuvent être affichés en regard du CarouselView. Cette opération peut être effectuée avec le contrôle IndicatorView :

<StackLayout>
    <CarouselView ItemsSource="{Binding Monkeys}"
                  IndicatorView="indicatorView">
        <CarouselView.ItemTemplate>
            <!-- DataTemplate that defines item appearance -->
        </CarouselView.ItemTemplate>
    </CarouselView>
    <IndicatorView x:Name="indicatorView"
                   IndicatorColor="LightGray"
                   SelectedIndicatorColor="DarkGray"
                   HorizontalOptions="Center" />
</StackLayout>

Dans cet exemple, le IndicatorView est rendu sous le CarouselView, avec un indicateur pour chaque élément du CarouselView. Le IndicatorView est rempli avec des données en définissant la propriété CarouselView.IndicatorView sur l’objet IndicatorView. Chaque indicateur est un cercle gris clair, tandis que l’indicateur qui représente l’élément actuel dans le CarouselView est gris foncé :

Capture d’écran d’un CarouselView et d’un IndicatorView.

Important

La définition de la propriété CarouselView.IndicatorView entraîne la liaison de propriétéIndicatorView.Position à la propriété CarouselView.Position et la liaison de propriété IndicatorView.ItemsSource à la propriété CarouselView.ItemsSource.

Pour découvrir plus d’informations sur les indicateurs, consultez IndicatorView.

Menu contextuels

CarouselView prend en charge les menus contextuels pour les éléments de données via SwipeView, qui révèle le menu contextuel avec un mouvement de balayage. SwipeView est un contrôle conteneur qui enveloppe un élément de contenu et fournit des éléments de menu contextuel pour cet élément de contenu. Les menus contextuels sont donc implémentés pour CarouselView en créant un SwipeView qui définit le contenu autour duquel SwipeView est enveloppé et les éléments de menu contextuel révélés par le mouvement de balayage. Pour ce faire, ajoutez un SwipeView à DataTemplate qui définit l’apparence de chaque élément de données dans CarouselView :

<CarouselView x:Name="carouselView"
              ItemsSource="{Binding Monkeys}">
    <CarouselView.ItemTemplate>
        <DataTemplate>
            <StackLayout>
                    <Frame HasShadow="True"
                           BorderColor="DarkGray"
                           CornerRadius="5"
                           Margin="20"
                           HeightRequest="300"
                           HorizontalOptions="Center"
                           VerticalOptions="CenterAndExpand">
                        <SwipeView>
                            <SwipeView.TopItems>
                                <SwipeItems>
                                    <SwipeItem Text="Favorite"
                                               IconImageSource="favorite.png"
                                               BackgroundColor="LightGreen"
                                               Command="{Binding Source={x:Reference carouselView}, Path=BindingContext.FavoriteCommand}"
                                               CommandParameter="{Binding}" />
                                </SwipeItems>
                            </SwipeView.TopItems>
                            <SwipeView.BottomItems>
                                <SwipeItems>
                                    <SwipeItem Text="Delete"
                                               IconImageSource="delete.png"
                                               BackgroundColor="LightPink"
                                               Command="{Binding Source={x:Reference carouselView}, Path=BindingContext.DeleteCommand}"
                                               CommandParameter="{Binding}" />
                                </SwipeItems>
                            </SwipeView.BottomItems>
                            <StackLayout>
                                <!-- Define item appearance -->
                            </StackLayout>
                        </SwipeView>
                    </Frame>
            </StackLayout>
        </DataTemplate>
    </CarouselView.ItemTemplate>
</CarouselView>

Le code C# équivalent est :

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

carouselView.ItemTemplate = new DataTemplate(() =>
{
    StackLayout stackLayout = new StackLayout();
    Frame frame = new Frame { ... };

    SwipeView swipeView = new SwipeView();
    SwipeItem favoriteSwipeItem = new SwipeItem
    {
        Text = "Favorite",
        IconImageSource = "favorite.png",
        BackgroundColor = Colors.LightGreen
    };
    favoriteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.FavoriteCommand", source: carouselView));
    favoriteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");

    SwipeItem deleteSwipeItem = new SwipeItem
    {
        Text = "Delete",
        IconImageSource = "delete.png",
        BackgroundColor = Colors.LightPink
    };
    deleteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.DeleteCommand", source: carouselView));
    deleteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");

    swipeView.TopItems = new SwipeItems { favoriteSwipeItem };
    swipeView.BottomItems = new SwipeItems { deleteSwipeItem };

    StackLayout swipeViewStackLayout = new StackLayout { ... };
    swipeView.Content = swipeViewStackLayout;
    frame.Content = swipeView;
    stackLayout.Add(frame);

    return stackLayout;
});

Dans cet exemple, le contenu SwipeView est un StackLayout qui définit l’apparence de chaque élément qui est entouré par un Frame dans le CarouselView. Les éléments de balayage sont utilisés pour effectuer des actions sur le contenu SwipeView et sont révélés lorsque l’utilisateur effectue un balayage du contrôle à partir du bas et du haut :

Capture d’écran d’un élément de menu contextuel bas de CarouselView.Capture d’écran d’un élément de menu contextuel haut de CarouselView.

SwipeView prend en charge quatre directions de balayage différentes, la direction de balayage étant définie par la collection SwipeItems directionnelle à laquelle les objets SwipeItems sont ajoutés. Par défaut, un élément de balayage est exécuté lorsque l’utilisateur appuie dessus. En outre, une fois qu’un élément de balayage a été exécuté, les éléments de balayage sont masqués et le contenu SwipeView est réaffiché. Toutefois, il est possible de modifier ces comportements.

Pour plus d’informations sur le contrôle SwipeView, consultez SwipeView.

Tirer pour actualiser

CarouselView prend en charge la fonctionnalité « balayer pour actualiser » via RefreshView, ce qui permet d’actualiser les données affichées en extrayant les éléments. RefreshView est un contrôle conteneur qui fournit une fonctionnalité « tirer pour actualiser » à son enfant, à condition que ce dernier prenne en charge le contenu avec défilement. La fonctionnalité « tirer pour actualiser » est donc implémentée pour CarouselView en le définissant comme enfant de RefreshView :

<RefreshView IsRefreshing="{Binding IsRefreshing}"
             Command="{Binding RefreshCommand}">
    <CarouselView ItemsSource="{Binding Animals}">
        ...
    </CarouselView>
</RefreshView>

Le code C# équivalent est :

RefreshView refreshView = new RefreshView();
ICommand refreshCommand = new Command(() =>
{
    // IsRefreshing is true
    // Refresh data here
    refreshView.IsRefreshing = false;
});
refreshView.Command = refreshCommand;

CarouselView carouselView = new CarouselView();
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
refreshView.Content = carouselView;
// ...

Lorsque l’utilisateur lance une actualisation, le ICommand défini par la propriété Command est exécuté, ce qui doit actualiser les éléments affichés. Une visualisation d’actualisation, qui se compose d’un cercle de progression animé, s’affiche pendant l’actualisation :

Capture d’écran de « balayer pour actualiser » de CarouselView.

La valeur de la propriété RefreshView.IsRefreshing indique l’état actuel de RefreshView. Quand une actualisation est déclenchée par l’utilisateur, cette propriété passe automatiquement à true. Une fois l’actualisation terminée, vous devez rétablir la valeur false de la propriété.

Pour plus d’informations sur RefreshView, consultez RefreshView.

Charger des données de manière incrémentielle

CarouselView prend en charge la virtualisation incrémentielle des données à mesure que l’utilisateur réalise un défilement. Cela permet des scénarios tels que le chargement asynchrone d’une page de données à partir d’un service web, à mesure que l’utilisateur fait défiler la page. En outre, vous pouvez configurer le moment auquel plus de données sont chargées pour que les utilisateurs ne voient pas d’espace vide ou ne soient pas empêchés de faire défiler la page.

CarouselView définit les propriétés suivantes pour contrôler le chargement incrémentiel des données :

  • RemainingItemsThreshold, de type int, qui correspond au seuil d’éléments non encore visibles dans la liste auquel l’événement RemainingItemsThresholdReached est déclenché.
  • RemainingItemsThresholdReachedCommand, de type ICommand, qui est exécuté lorsque RemainingItemsThreshold est atteint.
  • RemainingItemsThresholdReachedCommandParameter, de type object : paramètre passé à la commande RemainingItemsThresholdReachedCommand.

CarouselView définit également un événement RemainingItemsThresholdReached qui est déclenché lorsque le CarouselView fait l’objet d’un défilement suffisamment important pour que les éléments RemainingItemsThreshold ne soient pas affichés. Cet événement peut être géré pour charger plus d’éléments. En outre, lorsque l’événement RemainingItemsThresholdReached est déclenché, RemainingItemsThresholdReachedCommand est exécuté, ce qui permet le chargement incrémentiel des données dans un viewmodel.

La valeur par défaut de la propriété RemainingItemsThreshold est –1, ce qui indique que l’événement RemainingItemsThresholdReached n’est jamais déclenché. Lorsque la valeur de la propriété est 0, l’événement RemainingItemsThresholdReached est déclenché lorsque l’élément final de ItemsSource est affiché. Pour les valeurs supérieures à 0, l’événement RemainingItemsThresholdReached est déclenché lorsque ItemsSource contient le nombre d’éléments qui n’ont pas encore été atteints par défilement.

Remarque

CarouselView valide la propriété RemainingItemsThreshold pour que sa valeur soit toujours supérieure ou égale à –1.

L’exemple XAML suivant montre un CarouselView qui charge les données de manière incrémentielle :

<CarouselView ItemsSource="{Binding Animals}"
              RemainingItemsThreshold="2"
              RemainingItemsThresholdReached="OnCarouselViewRemainingItemsThresholdReached"
              RemainingItemsThresholdReachedCommand="{Binding LoadMoreDataCommand}">
    ...
</CarouselView>

Le code C# équivalent est :

CarouselView carouselView = new CarouselView
{
    RemainingItemsThreshold = 2
};
carouselView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
carouselView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");

Dans cet exemple de code, l’événement RemainingItemsThresholdReached se déclenche lorsque deux éléments n’ont pas encore été atteints par défilement et, en réponse, exécute le gestionnaire d’événements OnCollectionViewRemainingItemsThresholdReached :

void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
    // Retrieve more data here and add it to the CollectionView's ItemsSource collection.
}

Remarque

Vous pouvez également charger des données de manière incrémentielle en liant RemainingItemsThresholdReachedCommand à une implémentation ICommand dans le viewmodel.