Xamarin.Forms Układ obiektu CollectionView

CollectionView definiuje następujące właściwości, które kontrolują układ:

Te właściwości są wspierane przez BindableProperty obiekty, co oznacza, że właściwości mogą być obiektami docelowymi powiązań danych.

Domyślnie obiekt CollectionView będzie wyświetlać swoje elementy na liście pionowej. Można jednak użyć dowolnego z następujących układów:

  • Lista pionowa — pojedyncza lista kolumn, która rośnie w pionie w miarę dodawania nowych elementów.
  • Lista pozioma — pojedyncza lista wierszy, która rośnie w poziomie w miarę dodawania nowych elementów.
  • Siatka pionowa — siatka wielokolumna, która rośnie w pionie w miarę dodawania nowych elementów.
  • Siatka pozioma — siatka wielowierszowa, która rośnie w poziomie w miarę dodawania nowych elementów.

Te układy można określić, ustawiając ItemsLayout właściwość na klasę pochodzącą ItemsLayout z klasy . Ta klasa definiuje następujące właściwości:

Te właściwości są wspierane przez BindableProperty obiekty, co oznacza, że właściwości mogą być obiektami docelowymi powiązań danych. Aby uzyskać więcej informacji na temat punktów przyciągania, zobacz Snap points (Punkty przyciągania) w przewodniku Xamarin.Forms CollectionView Scrolling (Przewijanie widoku kolekcji).

Wyliczenie ItemsLayoutOrientation definiuje następujące elementy członkowskie:

  • Vertical wskazuje, że CollectionView element będzie rozszerzany w pionie w miarę dodawania elementów.
  • Horizontal wskazuje, że CollectionView element będzie rozszerzany w poziomie w miarę dodawania elementów.

Klasa LinearItemsLayout dziedziczy z ItemsLayout klasy i definiuje ItemSpacing właściwość typu double, która reprezentuje puste miejsce wokół każdego elementu. Wartość domyślna tej właściwości to 0, a jej wartość musi być zawsze większa lub równa 0. Klasa LinearItemsLayout definiuje również statyczne Vertical i Horizontal składowe. Te elementy członkowskie mogą służyć do tworzenia odpowiednio list pionowych lub poziomych. Alternatywnie LinearItemsLayout można utworzyć obiekt, określając element ItemsLayoutOrientation członkowski wyliczenia jako argument.

Klasa GridItemsLayout dziedziczy z ItemsLayout klasy i definiuje następujące właściwości:

  • VerticalItemSpacing, typu double, który reprezentuje pionowe puste miejsce wokół każdego elementu. Wartość domyślna tej właściwości to 0, a jej wartość musi być zawsze większa lub równa 0.
  • HorizontalItemSpacing, typu double, który reprezentuje poziome puste miejsce wokół każdego elementu. Wartość domyślna tej właściwości to 0, a jej wartość musi być zawsze większa lub równa 0.
  • Span, typu int, który reprezentuje liczbę kolumn lub wierszy do wyświetlenia w siatce. Wartość domyślna tej właściwości to 1, a jej wartość musi być zawsze większa lub równa 1.

Te właściwości są wspierane przez BindableProperty obiekty, co oznacza, że właściwości mogą być obiektami docelowymi powiązań danych.

Uwaga

CollectionView używa aparatów układu natywnego do wykonywania układu.

Pionowa lista

Domyślnie CollectionView jego elementy będą wyświetlane w układzie listy pionowej. W związku z tym nie jest konieczne ustawienie ItemsLayout właściwości tak, aby korzystała z tego układu:

<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>

Jednak w przypadku kompletności w języku XAML CollectionView można ustawić ustawienie , aby wyświetlić jego elementy na liście pionowej, ustawiając jej ItemsLayout właściwość na :VerticalList

<CollectionView ItemsSource="{Binding Monkeys}"
                ItemsLayout="VerticalList">
    ...
</CollectionView>

Alternatywnie można to zrobić, ustawiając ItemsLayout właściwość na LinearItemsLayout obiekt, określając VerticalItemsLayoutOrientation element członkowski wyliczenia jako Orientation wartość właściwości:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = LinearItemsLayout.Vertical
};

Powoduje to utworzenie pojedynczej listy kolumn, która rośnie w pionie w miarę dodawania nowych elementów:

Zrzut ekranu przedstawiający układ listy pionowej CollectionView w systemach iOS i Android

Lista pozioma

W języku XAML obiekt CollectionView może wyświetlać swoje elementy na liście poziomej, ustawiając jej ItemsLayout właściwość na :HorizontalList

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

Można również wykonać ten układ, ustawiając ItemsLayout właściwość na LinearItemsLayout obiekt, określając HorizontalItemsLayoutOrientation element członkowski wyliczenia jako Orientation wartość właściwości:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Horizontal" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = LinearItemsLayout.Horizontal
};

Powoduje to utworzenie pojedynczej listy wierszy, która rośnie w poziomie w miarę dodawania nowych elementów:

Zrzut ekranu przedstawiający układ listy poziomej CollectionView w systemach iOS i Android

Siatka pionowa

W języku XAML obiekt CollectionView może wyświetlać swoje elementy w siatce pionowej, ustawiając jej ItemsLayout właściwość na :VerticalGrid

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

Można również wykonać ten układ, ustawiając ItemsLayout właściwość na GridItemsLayout obiekt, którego Orientation właściwość jest ustawiona na Vertical:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Vertical"
                        Span="2" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};

Domyślnie pionowy GridItemsLayout element będzie wyświetlał elementy w jednej kolumnie. Jednak w tym przykładzie GridItemsLayout.Span właściwość jest ustawiana na 2. Powoduje to, że siatka dwukolumna rośnie w pionie w miarę dodawania nowych elementów:

Zrzut ekranu przedstawiający układ siatki pionowej CollectionView w systemach iOS i Android

Siatka pozioma

W języku XAML obiekt CollectionView może wyświetlać swoje elementy w siatce poziomej, ustawiając jej ItemsLayout właściwość na :HorizontalGrid

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

Można również wykonać ten układ, ustawiając ItemsLayout właściwość na GridItemsLayout obiekt, którego Orientation właściwość jest ustawiona na Horizontal:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Horizontal"
                        Span="4" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};

Domyślnie poziome GridItemsLayout elementy będą wyświetlane w jednym wierszu. Jednak w tym przykładzie GridItemsLayout.Span właściwość ustawia wartość 4. Powoduje to utworzenie siatki z czterema wierszami, która rośnie w poziomie w miarę dodawania nowych elementów:

Zrzut ekranu przedstawiający układ siatki poziomej CollectionView w systemach iOS i Android

Nagłówki i stopki

CollectionView może przedstawiać nagłówek i stopkę, która przewija się z elementami na liście. Nagłówek i stopka mogą być ciągami, widokami lub DataTemplate obiektami.

CollectionView definiuje następujące właściwości określania nagłówka i stopki:

  • Header, typu object, określa ciąg, powiązanie lub widok, który będzie wyświetlany na początku listy.
  • HeaderTemplate, typu DataTemplate, określa DataTemplate , aby użyć do formatowania Header.
  • Footer, typu object, określa ciąg, powiązanie lub widok, który będzie wyświetlany na końcu listy.
  • FooterTemplate, typu DataTemplate, określa DataTemplate , aby użyć do formatowania Footer.

Te właściwości są wspierane przez BindableProperty obiekty, co oznacza, że właściwości mogą być obiektami docelowymi powiązań danych.

Po dodaniu nagłówka do układu, który rośnie w poziomie, od lewej do prawej, nagłówek jest wyświetlany po lewej stronie listy. Podobnie po dodaniu stopki do układu, który rośnie w poziomie, od lewej do prawej, stopka jest wyświetlana po prawej stronie listy.

Właściwości Header i Footer można ustawić na string wartości, jak pokazano w poniższym przykładzie:

<CollectionView ItemsSource="{Binding Monkeys}"
                Header="Monkeys"
                Footer="2019">
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    Header = "Monkeys",
    Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Ten kod powoduje wyświetlenie poniższych zrzutów ekranu z nagłówkiem widocznym na zrzucie ekranu systemu iOS i stopką pokazaną na zrzucie ekranu systemu Android:

Zrzut ekranu przedstawiający nagłówek i stopkę ciągu CollectionView w systemach iOS i Android

Właściwości Header i Footer można ustawić na widok. Może to być pojedynczy widok lub widok zawierający wiele widoków podrzędnych. W poniższym przykładzie pokazano Header właściwości i Footer dla każdego zestawu StackLayout obiektów zawierającego Label obiekt:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.Header>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Monkeys"
                   FontSize="Small"
                   FontAttributes="Bold" />
        </StackLayout>
    </CollectionView.Header>
    <CollectionView.Footer>
        <StackLayout BackgroundColor="LightGray">
            <Label Margin="10,0,0,0"
                   Text="Friends of Xamarin Monkey"
                   FontSize="Small"
                   FontAttributes="Bold" />
        </StackLayout>
    </CollectionView.Footer>
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    Header = new StackLayout
    {
        Children =
        {
            new Label { Text = "Monkeys", ... }
        }
    },
    Footer = new StackLayout
    {
        Children =
        {
            new Label { Text = "Friends of Xamarin Monkey", ... }
        }
    }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Ten kod powoduje wyświetlenie poniższych zrzutów ekranu z nagłówkiem widocznym na zrzucie ekranu systemu iOS i stopką pokazaną na zrzucie ekranu systemu Android:

Zrzut ekranu przedstawiający nagłówek i stopkę CollectionView przy użyciu widoków w systemach iOS i Android

Właściwości HeaderTemplate i FooterTemplate można ustawić na DataTemplate obiekty, które są używane do formatowania nagłówka i stopki. W tym scenariuszu Header właściwości i Footer muszą być powiązane z bieżącym źródłem, aby szablony były stosowane, jak pokazano w poniższym przykładzie:

<CollectionView ItemsSource="{Binding Monkeys}"
                Header="{Binding .}"
                Footer="{Binding .}">
    <CollectionView.HeaderTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Monkeys"
                       FontSize="Small"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.HeaderTemplate>
    <CollectionView.FooterTemplate>
        <DataTemplate>
            <StackLayout BackgroundColor="LightGray">
                <Label Margin="10,0,0,0"
                       Text="Friends of Xamarin Monkey"
                       FontSize="Small"
                       FontAttributes="Bold" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.FooterTemplate>
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    HeaderTemplate = new DataTemplate(() =>
    {
        return new StackLayout { };
    }),
    FooterTemplate = new DataTemplate(() =>
    {
        return new StackLayout { };
    })
};
collectionView.SetBinding(ItemsView.HeaderProperty, ".");
collectionView.SetBinding(ItemsView.FooterProperty, ".");
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

Ten kod powoduje wyświetlenie poniższych zrzutów ekranu z nagłówkiem widocznym na zrzucie ekranu systemu iOS i stopką pokazaną na zrzucie ekranu systemu Android:

Zrzut ekranu przedstawiający nagłówek i stopkę CollectionView przy użyciu szablonów w systemach iOS i Android

Odstępy między elementami

Domyślnie nie ma spacji między każdym elementem w elemencie CollectionView. To zachowanie można zmienić, ustawiając właściwości układu elementów używanego CollectionViewprzez element .

CollectionView Gdy właściwość ustawia jej ItemsLayout właściwość LinearItemsLayout na obiekt, LinearItemsLayout.ItemSpacing można ustawić właściwość na wartość reprezentującą double przestrzeń między elementami:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           ItemSpacing="20" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Uwaga

Właściwość LinearItemsLayout.ItemSpacing ma ustawiony wywołanie zwrotne walidacji, co gwarantuje, że wartość właściwości jest zawsze większa lub równa 0.

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
        ItemSpacing = 20
    }
};

Ten kod powoduje wyświetlenie pionowej listy z jedną kolumną, która ma odstępy 20 między elementami:

Zrzut ekranu przedstawiający obiekt CollectionView z odstępami między elementami w systemach iOS i Android

CollectionView Gdy właściwość ustawia na ItemsLayoutGridItemsLayout obiekt, GridItemsLayout.VerticalItemSpacing właściwości i GridItemsLayout.HorizontalItemSpacing można ustawić na double wartości reprezentujące puste miejsce w pionie i w poziomie między elementami:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
       <GridItemsLayout Orientation="Vertical"
                        Span="2"
                        VerticalItemSpacing="20"
                        HorizontalItemSpacing="30" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

Uwaga

Właściwości GridItemsLayout.VerticalItemSpacing i GridItemsLayout.HorizontalItemSpacing mają ustawione wywołania zwrotne weryfikacji, które zapewniają, że wartości właściwości są zawsze większe lub równe 0.

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
    {
        VerticalItemSpacing = 20,
        HorizontalItemSpacing = 30
    }
};

Ten kod powoduje, że pionowa siatka dwukolumna, która ma odstęp pionowy 20 między elementami, a odstępem poziomym 30 między elementami:

Zrzut ekranu przedstawiający obiekt CollectionView z odstępami między elementami w systemie Android

Ustalanie rozmiaru elementu

Domyślnie każdy element w obiekcie CollectionView jest indywidualnie mierzony i ma rozmiar, pod warunkiem, że elementy interfejsu użytkownika w elemencie DataTemplate nie określają stałych rozmiarów. To zachowanie, które można zmienić, jest określane przez CollectionView.ItemSizingStrategy wartość właściwości. Tę wartość właściwości można ustawić na jeden z elementów ItemSizingStrategy członkowskich wyliczenia:

  • MeasureAllItems – każdy element jest mierzony indywidualnie. Jest to wartość domyślna.
  • MeasureFirstItem — tylko pierwszy element jest mierzony, a wszystkie kolejne elementy mają taki sam rozmiar jak pierwszy element.

Ważne

Strategia MeasureFirstItem ustalania rozmiaru spowoduje zwiększenie wydajności w sytuacjach, w których rozmiar elementu ma być jednolity we wszystkich elementach.

Poniższy przykład kodu przedstawia ustawienie ItemSizingStrategy właściwości:

<CollectionView ...
                ItemSizingStrategy="MeasureFirstItem">
    ...
</CollectionView>

Równoważny kod języka C# to:

CollectionView collectionView = new CollectionView
{
    ...
    ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};

Dynamiczna zmiana rozmiaru elementów

Elementy w obiekcie CollectionView mogą być dynamicznie zmieniane w czasie wykonywania, zmieniając właściwości powiązane z układem elementów w obiekcie DataTemplate. Na przykład poniższy przykład kodu zmienia HeightRequest właściwości Image i WidthRequest obiektu:

void OnImageTapped(object sender, EventArgs e)
{
    Image image = sender as Image;
    image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}

Procedura OnImageTapped obsługi zdarzeń jest wykonywana w odpowiedzi na obiekt, który jest naciśnięty Image , i zmienia wymiary obrazu, tak aby był łatwiej wyświetlany:

Zrzut ekranu przedstawiający obiekt CollectionView z dynamicznym ustalaniem rozmiaru elementów w systemach iOS i Android

Układ od prawej do lewej

CollectionView może układać jego zawartość w kierunku przepływu od prawej do lewej, ustawiając jej FlowDirection właściwość na RightToLeft. FlowDirection Jednak właściwość powinna być ustawiana na stronie lub układzie głównym, co powoduje, że wszystkie elementy w obrębie strony lub układu głównego powinny odpowiadać na kierunek przepływu:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CollectionViewDemos.Views.VerticalListFlowDirectionPage"
             Title="Vertical list (RTL FlowDirection)"
             FlowDirection="RightToLeft">
    <StackLayout Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}">
            ...
        </CollectionView>
    </StackLayout>
</ContentPage>

Wartość domyślna FlowDirection elementu z elementem nadrzędnym to MatchParent. CollectionView W związku z tym właściwość dziedziczy FlowDirection wartość właściwości z StackLayoutklasy , która z kolei dziedziczy FlowDirection wartość właściwości z ContentPageklasy . Spowoduje to wyświetlenie układu od prawej do lewej pokazanego na poniższych zrzutach ekranu:

Zrzut ekranu przedstawiający układ listy pionowej CollectionView od prawej do lewej w systemach iOS i Android

Aby uzyskać więcej informacji na temat kierunku przepływu, zobacz Lokalizacja od prawej do lewej.