Xamarin.Forms Данные CollectionView

Download Sample Скачайте пример

CollectionView включает следующие свойства, определяющие отображаемые данные и его внешний вид:

  • ItemsSourceIEnumerableТип , указывает коллекцию отображаемых элементов и имеет значение nullпо умолчанию.
  • ItemTemplateDataTemplateТип , указывает шаблон, применяемый к каждому элементу в коллекции отображаемых элементов.

Эти свойства поддерживаются BindableProperty объектами, что означает, что свойства могут быть целевыми объектами привязки данных.

Примечание.

CollectionView определяет ItemsUpdatingScrollMode свойство, представляющее поведение CollectionView прокрутки при добавлении в него новых элементов. Дополнительные сведения об этом свойстве см. в разделе "Управление положением прокрутки" при добавлении новых элементов.

CollectionView поддерживает добавочную виртуализацию данных по мере прокрутки пользователем. Дополнительные сведения см. в разделе "Загрузка данных" постепенно.

Заполнение CollectionView данными

A CollectionView заполняется данными, задав свойству ItemsSource любую коллекцию, которая реализует IEnumerable. По умолчанию CollectionView отображаются элементы в вертикальном списке.

Внимание

CollectionView Если требуется обновить элементы при добавлении, удалении или изменении в базовой коллекции, базовая коллекция должна быть IEnumerable коллекцией, которая отправляет уведомления об изменении свойств, напримерObservableCollection.

CollectionView можно заполнить данными с помощью привязки данных для привязки его ItemsSource свойства к IEnumerable коллекции. В XAML это достигается с расширением Binding разметки:

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

Эквивалентный код на C# выглядит так:

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

В этом примере ItemsSource данные свойств привязываются к Monkeys свойству подключенного представления.

Примечание.

Скомпилированные привязки можно включить для повышения производительности привязки данных в Xamarin.Forms приложениях. Дополнительные сведения см. в статье Скомпилированные привязки.

Сведения об изменении макета см. в CollectionView разделе Xamarin.Forms "Макет CollectionView". Сведения о том, как определить внешний вид каждого элемента в элементе CollectionView, см. в разделе "Определение внешнего вида элемента". Дополнительные сведения о привязке данных см. в разделе Привязка данных Xamarin.Forms.

Предупреждение

CollectionView вызовет исключение, если оно ItemsSource обновляется из потока пользовательского интерфейса.

Определение внешнего вида элемента

Внешний вид каждого элемента в CollectionView объекте можно определить, задав CollectionView.ItemTemplate для свойства значение DataTemplate:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <Grid Padding="10">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition Width="Auto" />
                </Grid.ColumnDefinitions>
                <Image Grid.RowSpan="2"
                       Source="{Binding ImageUrl}"
                       Aspect="AspectFill"
                       HeightRequest="60"
                       WidthRequest="60" />
                <Label Grid.Column="1"
                       Text="{Binding Name}"
                       FontAttributes="Bold" />
                <Label Grid.Row="1"
                       Grid.Column="1"
                       Text="{Binding Location}"
                       FontAttributes="Italic"
                       VerticalOptions="End" />
            </Grid>
        </DataTemplate>
    </CollectionView.ItemTemplate>
    ...
</CollectionView>

Эквивалентный код на C# выглядит так:

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

collectionView.ItemTemplate = new DataTemplate(() =>
{
    Grid grid = new Grid { Padding = 10 };
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

    Image image = new Image { Aspect = Aspect.AspectFill, HeightRequest = 60, WidthRequest = 60 };
    image.SetBinding(Image.SourceProperty, "ImageUrl");

    Label nameLabel = new Label { FontAttributes = FontAttributes.Bold };
    nameLabel.SetBinding(Label.TextProperty, "Name");

    Label locationLabel = new Label { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.End };
    locationLabel.SetBinding(Label.TextProperty, "Location");

    Grid.SetRowSpan(image, 2);

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

    return grid;
});

Элементы, указанные в DataTemplate определении внешнего вида каждого элемента в списке. В примере макет в пределах объекта DataTemplate управляется Grid. Image Содержит Grid объект и два Label объекта, которые привязываются ко свойствам Monkey класса:

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

На следующих снимках экрана показан результат создания шаблонов каждого элемента в списке:

Screenshot of CollectionView where each item is templated, on iOS and Android

Дополнительные сведения о шаблонах данных см. в разделе Общие сведения о шаблонах данныхXamarin.Forms.

Выбор внешнего вида элемента во время выполнения

Внешний вид каждого элемента в объекте CollectionView можно выбрать во время выполнения на основе значения элемента, задав свойству CollectionView.ItemTemplateDataTemplateSelector объект:

<ContentPage ...
             xmlns:controls="clr-namespace:CollectionViewDemos.Controls">
    <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>

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

Эквивалентный код на C# выглядит так:

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

Для ItemTemplate свойства задан MonkeyDataTemplateSelector объект. В следующем примере показан 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;
    }
}

Класс MonkeyDataTemplateSelector определяет AmericanMonkey и OtherMonkeyDataTemplate свойства, которые задаются различными шаблонами данных. Переопределение OnSelectTemplate возвращает AmericanMonkey шаблон, который отображает имя обезьяны и расположение в подростке, когда имя обезьяны содержит "Америка". Если имя обезьяны не содержит "Америка", переопределение возвращает OtherMonkey шаблон, OnSelectTemplate который отображает имя обезьяны и расположение в серебре:

Screenshot of CollectionView runtime item template selection, on iOS and Android

Дополнительные сведения о селекторах шаблонов данных см. в разделе "Создание Xamarin.Forms объекта DataTemplateSelector".

Внимание

При использовании CollectionViewникогда не задается корневой элемент объектов DataTemplateViewCell. Это приведет к возникновению исключения из-за CollectionView отсутствия концепции ячеек.

Контекстные меню

CollectionView поддерживает контекстные меню для элементов данных с помощью SwipeViewконтекстного меню с жестом прокрутки. Это SwipeView элемент управления контейнером, который обтекает элемент содержимого и предоставляет элементы контекстного меню для этого элемента содержимого. Таким образом, контекстные меню реализуются для создания CollectionViewSwipeView , который определяет содержимое, которое SwipeView обтекает, и элементы контекстного меню, отображаемые жестом прокрутки. Это достигается путем задания SwipeView в качестве корневого представления в DataTemplate представлении, определяющем внешний вид каждого элемента данных в CollectionView:

<CollectionView x:Name="collectionView"
                ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <SwipeView>
                <SwipeView.LeftItems>
                    <SwipeItems>
                        <SwipeItem Text="Favorite"
                                   IconImageSource="favorite.png"
                                   BackgroundColor="LightGreen"
                                   Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
                                   CommandParameter="{Binding}" />
                        <SwipeItem Text="Delete"
                                   IconImageSource="delete.png"
                                   BackgroundColor="LightPink"
                                   Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
                                   CommandParameter="{Binding}" />
                    </SwipeItems>
                </SwipeView.LeftItems>
                <Grid BackgroundColor="White"
                      Padding="10">
                    <!-- Define item appearance -->
                </Grid>
            </SwipeView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

Эквивалентный код на C# выглядит так:

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

collectionView.ItemTemplate = new DataTemplate(() =>
{
    // Define item appearance
    Grid grid = new Grid { Padding = 10, BackgroundColor = Color.White };
    // ...

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

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

    swipeView.LeftItems = new SwipeItems { favoriteSwipeItem, deleteSwipeItem };
    swipeView.Content = grid;    
    return swipeView;
});

В этом примере содержимое SwipeView определяет Grid внешний вид каждого элемента в элементе CollectionView. Элементы прокрутки используются для выполнения действий с SwipeView содержимым и отображаются при прокрутке элемента управления влево:

Screenshot of CollectionView context menu items, on iOS and Android

SwipeView поддерживает четыре разных направления прокрутки, а направление прокрутки определяется коллекцией направлений SwipeItemsSwipeItems , к которым добавляются объекты. По умолчанию элемент пальцем выполняется при нажатии пользователя. Кроме того, после выполнения элемента прокрутки элементы пальцем скрыты, а SwipeView содержимое отображается повторно. Однако эти действия можно изменить.

Дополнительные сведения об элементе SwipeView управления см. в разделе Xamarin.Forms "Пальцем".

Потяните, чтобы обновить

CollectionView поддерживает вытягивание для обновления функциональных возможностей с помощью RefreshViewфункции, которая позволяет обновлять данные, отображаемые путем извлечения списка элементов. Это RefreshView элемент управления контейнером, предоставляющий возможность извлечения для обновления функциональных возможностей дочернего элемента, при условии, что дочерний элемент поддерживает прокручиваемое содержимое. Таким образом, вытягивание для обновления реализуется путем CollectionView задания его в качестве дочернего RefreshViewэлемента:

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

Эквивалентный код на C# выглядит так:

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

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
refreshView.Content = collectionView;
// ...

Когда пользователь инициирует обновление, выполняется определенное Command свойством, ICommand которое должно обновить отображаемые элементы. Визуализация обновления отображается во время обновления, которая состоит из анимированного круга выполнения:

Screenshot of CollectionView pull-to-refresh, on iOS and Android

Значение RefreshView.IsRefreshing свойства указывает текущее состояние RefreshViewобъекта. Когда обновление активируется пользователем, это свойство автоматически переходит в true. После завершения обновления необходимо сбросить свойство falseв значение .

Дополнительные сведения см. в RefreshViewразделе Xamarin.Forms RefreshView.

Добавочная загрузка данных

CollectionView поддерживает добавочную виртуализацию данных по мере прокрутки пользователем. Это позволяет выполнять такие сценарии, как асинхронная загрузка страницы данных из веб-службы при прокрутке пользователя. Кроме того, точка загрузки дополнительных данных настраивается таким образом, чтобы пользователи не видели пустого места или остановлены от прокрутки.

CollectionView определяет следующие свойства для управления добавочной загрузкой данных:

  • RemainingItemsThresholdintТип , порог элементов, пока не видимых в списке, в котором RemainingItemsThresholdReached будет запущено событие.
  • RemainingItemsThresholdReachedCommandICommandтип , который выполняется при RemainingItemsThreshold достижении.
  • RemainingItemsThresholdReachedCommandParameter с типом object, который передается как параметр в RemainingItemsThresholdReachedCommand.

CollectionView также определяет RemainingItemsThresholdReached событие, которое запускается, когда CollectionView прокручивается достаточно далеко, что RemainingItemsThreshold элементы не отображались. Это событие можно обрабатывать для загрузки дополнительных элементов. Кроме того, при RemainingItemsThresholdReached запуске события выполняется выполнение, RemainingItemsThresholdReachedCommand что позволяет выполнять добавочную загрузку данных в режиме просмотра.

Значение RemainingItemsThreshold свойства по умолчанию — -1, указывающее, что RemainingItemsThresholdReached событие никогда не будет запущено. Если значение свойства равно 0, RemainingItemsThresholdReached событие будет запущено при отображении окончательного элемента в объекте ItemsSource . Для значений, превышающих 0, событие будет запущено, RemainingItemsThresholdReached когда ItemsSource содержится указанное число элементов, до которых еще не прокручено.

Примечание.

CollectionViewRemainingItemsThreshold проверяет свойство таким образом, чтобы его значение всегда было больше или равно -1.

В следующем примере XAML показано CollectionView , что данные загружаются постепенно.

<CollectionView ItemsSource="{Binding Animals}"
                RemainingItemsThreshold="5"
                RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
    ...
</CollectionView>

Эквивалентный код на C# выглядит так:

CollectionView collectionView = new CollectionView
{
    RemainingItemsThreshold = 5
};
collectionView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");

В этом примере кода событие запускается, RemainingItemsThresholdReached если еще не прокручено 5 элементов, а в ответ выполняется OnCollectionViewRemainingItemsThresholdReached обработчик событий:

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

Примечание.

Данные также можно загружать постепенно, привязывая RemainingItemsThresholdReachedCommand к ICommand реализации в режиме просмотра.