Элемент CarouselView представляет компонент для отображения данных в зацикленном прокручиваемом виде, в котором пользователи могут перемещаться по набору элементов, проводя пальцем по экрану или нажимая на указатель мыши.
Для установки данных у класса CarouselView определено свойство ItemsSource, которое принимает объект IEnumerable, то есть это может быть массив или список List или другой тип коллекций. Если же необходимо динамически добавлять данные в привязанный список, тогда применяется класс ObservableCollection.
Например, пусть данные представленны следующим классом Product, который описывает товар:
class Product { public string Name { get; set; } = ""; public string Description { get; set; } = ""; public string ImagePath { get; set; } = ""; }
свойство Name
указывает на название товара, свойство Description
- на некоторое описание, а
ImagePath
- на путь к файлу изображений.
Для хранения файлов изображений поместим в в проект в папку Resources/Images
несколько изображений-логотипов для разных товаров:
Чтобы отображать объекты CarouselView, необходимо задать шаблон с помощью свойства ItemsTemplate. Данное свойство принимает объект DataTemplate, который определяет шаблн данных.
Например, определим в коде C# следующую страницу:
namespace HelloApp; class StartPage : ContentPage { public StartPage() { CarouselView carouselView = new CarouselView { VerticalOptions = LayoutOptions.Start }; carouselView.ItemsSource = new List<Product> { new Product {Name="Huawei P50", ImagePath="huaweip50_sm.jpg", Description = "Цена 59000" }, new Product {Name="iPhone 14", ImagePath="iphone14_sm.jpg", Description = "Цена 65000" }, new Product {Name="Realme GT2 Pro", ImagePath="realmegt2pro_sm.jpg", Description = "Цена 41000" }, new Product {Name="Xiaomi 12X", ImagePath="xiaomi12x_sm.jpg", Description = "Цена 53999" }, }; // определяем шаблон данных carouselView.ItemTemplate = new DataTemplate(() => { Label header = new Label { FontAttributes = FontAttributes.Bold, HorizontalTextAlignment = TextAlignment.Center, FontSize = 18 }; header.SetBinding(Label.TextProperty, "Name"); Image image = new Image { WidthRequest= 150, HeightRequest = 150}; image.SetBinding(Image.SourceProperty, "ImagePath"); Label description = new Label { HorizontalTextAlignment = TextAlignment.Center }; description.SetBinding(Label.TextProperty, "Description"); StackLayout stackLayout = new StackLayout() { header, image, description}; Frame frame = new Frame(); frame.Content = stackLayout; return frame; }); Content = carouselView; } }
Здесь объекту CarouselView передается список из четырех товаров. Для определения шаблна отображения этих товаров свойству ItemTemplate
передается объект DataTemplate. Его конструктор принимает делегат Func<object>
.
Этот делегат возвращает визуальный компонент, который будет создаваться для каждого элемента списка и который устанавливает, как данные будут располагаться. В качестве визуального
компонента может выступать любой стандартный элемент графического интерфейса. В данном случае в качестве такого выступает элемент Frame
,
который, в свою очередь, располагает вложенные данные в виде вертикального стека.
Вертикальный стек содержит элементы, которые привязаны к различным свойствам отображаемого товара. Сначала идет метка, которая привязана к свойству Name отображаемого объекта Product. Дальше идет элемент Image для отображения картинки товара и затем метка Label для описания товара. пределяет структуру строки в ListView.
Конкретное отображение отличается от устройства. Например, на Windows все элементы растягиваются по ширине окна, а под элементами идет полоса прокрутки.:
На Android одномоменто отображается один элемент, список зациклен, а с помощью свайпа пальцем можно прокручивать список:
Аналогичный пример в коде Xaml:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage" xmlns:local="clr-namespace:HelloApp"> <VerticalStackLayout Padding="5"> <CarouselView> <CarouselView.ItemsSource> <x:Array Type="{x:Type local:Product}"> <local:Product Name="Huawei P50" ImagePath="huaweip50_sm.jpg" Description="Цена 59000" /> <local:Product Name="iPhone 14" ImagePath="iphone14_sm.jpg" Description="Цена 65000" /> <local:Product Name="Realme GT2 Pro" ImagePath="realmegt2pro_sm.jpg" Description="Цена 41000" /> <local:Product Name="Xiaomi 12X" ImagePath="xiaomi12x_sm.jpg" Description="Цена 53999" /> </x:Array> </CarouselView.ItemsSource> <CarouselView.ItemTemplate> <DataTemplate> <Frame> <VerticalStackLayout> <Label Text="{Binding Name}" FontAttributes="Bold" FontSize="18" HorizontalTextAlignment="Center"/> <Image WidthRequest="150" HeightRequest="150" Source="{Binding ImagePath}" /> <Label Text="{Binding Description}" HorizontalTextAlignment="Center" /> </VerticalStackLayout> </Frame> </DataTemplate> </CarouselView.ItemTemplate> </CarouselView> </VerticalStackLayout> </ContentPage>
Свойство IndicatorView позволяет установить индикатор перемещения по списку. Так, определим в XAML следующую страницу:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage" xmlns:local="clr-namespace:HelloApp"> <VerticalStackLayout Padding="5"> <CarouselView IndicatorView="indicatorView"> <CarouselView.ItemsSource> <x:Array Type="{x:Type local:Product}"> <local:Product Name="Huawei P50" ImagePath="huaweip50_sm.jpg" Description="Цена 59000" /> <local:Product Name="iPhone 14" ImagePath="iphone14_sm.jpg" Description="Цена 65000" /> <local:Product Name="Realme GT2 Pro" ImagePath="realmegt2pro_sm.jpg" Description="Цена 41000" /> <local:Product Name="Xiaomi 12X" ImagePath="xiaomi12x_sm.jpg" Description="Цена 53999" /> </x:Array> </CarouselView.ItemsSource> <CarouselView.ItemTemplate> <DataTemplate> <Frame> <VerticalStackLayout> <Label Text="{Binding Name}" FontAttributes="Bold" FontSize="18" HorizontalTextAlignment="Center"/> <Image WidthRequest="150" HeightRequest="150" Source="{Binding ImagePath}" /> <Label Text="{Binding Description}" HorizontalTextAlignment="Center" /> </VerticalStackLayout> </Frame> </DataTemplate> </CarouselView.ItemTemplate> </CarouselView> <IndicatorView Margin="0, 10, 0, 0" x:Name="indicatorView" IndicatorColor="LightGray" SelectedIndicatorColor="DarkGray" HorizontalOptions="Center" /> </VerticalStackLayout> </ContentPage>
Значение свойства IndicatorView - объект типа IndicatorView, в данном случае это элемент "indicatorView", который определен на странице после CarouselView.
По умолчанию CarouselView располагает элементы горизонтально. Но также можно расположить список вертикально. Для этого нам надо установить свойство
ItemsLayout. В качестве значения это свойство принимает объект LinearItemsLayout. Класс LinearItemsLayout
предоставляет свойство Orientation, которое задает направление элементов. Оно представляет перечисление ItemsLayoutOrientation
, в котором определены две константы
Horizontal
: расположение по горизонтали
Vertical
: расположение по вертикали
Пример, вертикальной ориентации в XAML:
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="HelloApp.MainPage" xmlns:local="clr-namespace:HelloApp"> <CarouselView> <CarouselView.ItemsLayout> <LinearItemsLayout Orientation="Vertical" /> </CarouselView.ItemsLayout> <CarouselView.ItemsSource> <x:Array Type="{x:Type local:Product}"> <local:Product Name="Huawei P50" ImagePath="huaweip50_sm.jpg" Description="Цена 59000" /> <local:Product Name="iPhone 14" ImagePath="iphone14_sm.jpg" Description="Цена 65000" /> <local:Product Name="Realme GT2 Pro" ImagePath="realmegt2pro_sm.jpg" Description="Цена 41000" /> <local:Product Name="Xiaomi 12X" ImagePath="xiaomi12x_sm.jpg" Description="Цена 53999" /> </x:Array> </CarouselView.ItemsSource> <CarouselView.ItemTemplate> <DataTemplate> <Frame Margin="20"> <VerticalStackLayout VerticalOptions="Center"> <Label Text="{Binding Name}" FontAttributes="Bold" FontSize="18" HorizontalTextAlignment="Center"/> <Image WidthRequest="150" HeightRequest="150" Source="{Binding ImagePath}" /> <Label Text="{Binding Description}" HorizontalTextAlignment="Center" /> </VerticalStackLayout> </Frame> </DataTemplate> </CarouselView.ItemTemplate> </CarouselView> </ContentPage>
Установка вертикальной ориентации в коде C#:
CarouselView carouselView = new CarouselView(); carouselView.ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical);