Condividi tramite


Xamarin.Forms CollectionView Layout

CollectionView definisce le proprietà seguenti che controllano il layout:

Queste proprietà sono supportate da BindableProperty oggetti , il che significa che le proprietà possono essere destinazioni di data binding.

Per impostazione predefinita, un oggetto CollectionView visualizzerà gli elementi in un elenco verticale. Tuttavia, è possibile usare uno dei layout seguenti:

  • Elenco verticale: elenco a colonna singola che aumenta verticalmente man mano che vengono aggiunti nuovi elementi.
  • Elenco orizzontale: un singolo elenco di righe che aumenta orizzontalmente man mano che vengono aggiunti nuovi elementi.
  • Griglia verticale: una griglia a più colonne che aumenta verticalmente man mano che vengono aggiunti nuovi elementi.
  • Griglia orizzontale: una griglia a più righe che aumenta orizzontalmente man mano che vengono aggiunti nuovi elementi.

Questi layout possono essere specificati impostando la ItemsLayout proprietà su classe che deriva dalla ItemsLayout classe . Questa classe definisce le proprietà seguenti:

Queste proprietà sono supportate da BindableProperty oggetti , il che significa che le proprietà possono essere destinazioni di data binding. Per altre informazioni sui punti di ancoraggio, vedere Punti di ancoraggio nella Xamarin.Forms guida a scorrimento CollectionView.

L'enumerazione ItemsLayoutOrientation definisce i membri seguenti:

  • Vertical indica che l'oggetto CollectionView verrà espanso verticalmente man mano che vengono aggiunti elementi.
  • Horizontal indica che l'oggetto CollectionView verrà espanso orizzontalmente man mano che vengono aggiunti elementi.

La LinearItemsLayout classe eredita dalla ItemsLayout classe e definisce una ItemSpacing proprietà di tipo double, che rappresenta lo spazio vuoto intorno a ogni elemento. Il valore predefinito di questa proprietà è 0 e il relativo valore deve essere sempre maggiore o uguale a 0. La LinearItemsLayout classe definisce anche membri e Horizontal staticiVertical. Questi membri possono essere usati rispettivamente per creare elenchi verticali o orizzontali. In alternativa, è possibile creare un LinearItemsLayout oggetto , specificando un membro di ItemsLayoutOrientation enumerazione come argomento.

La GridItemsLayout classe eredita dalla ItemsLayout classe e definisce le proprietà seguenti:

  • VerticalItemSpacing, di tipo double, che rappresenta lo spazio vuoto verticale intorno a ogni elemento. Il valore predefinito di questa proprietà è 0 e il relativo valore deve essere sempre maggiore o uguale a 0.
  • HorizontalItemSpacing, di tipo double, che rappresenta lo spazio vuoto orizzontale intorno a ogni elemento. Il valore predefinito di questa proprietà è 0 e il relativo valore deve essere sempre maggiore o uguale a 0.
  • Span, di tipo int, che rappresenta il numero di colonne o righe da visualizzare nella griglia. Il valore predefinito di questa proprietà è 1 e il relativo valore deve essere sempre maggiore o uguale a 1.

Queste proprietà sono supportate da BindableProperty oggetti , il che significa che le proprietà possono essere destinazioni di data binding.

Nota

CollectionView usa i motori di layout nativi per eseguire il layout.

Elenco verticale

Per impostazione predefinita, CollectionView gli elementi verranno visualizzati in un layout elenco verticale. Pertanto, non è necessario impostare la ItemsLayout proprietà per usare questo layout:

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

Tuttavia, per completezza, in XAML un CollectionView oggetto può essere impostato per visualizzare gli elementi in un elenco verticale impostandone la ItemsLayout proprietà su VerticalList:

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

In alternativa, questa operazione può essere eseguita impostando la ItemsLayout proprietà su un LinearItemsLayout oggetto , specificando il membro di Vertical ItemsLayoutOrientation enumerazione come valore della Orientation proprietà:

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

Il codice C# equivalente è il seguente:

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

In questo modo si ottiene un elenco a colonna singola, che aumenta verticalmente man mano che vengono aggiunti nuovi elementi:

Screenshot di un layout elenco verticale CollectionView in iOS e Android

Elenco orizzontale

In XAML un CollectionView oggetto può visualizzare gli elementi in un elenco orizzontale impostandone la ItemsLayout proprietà su 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>

In alternativa, questo layout può essere eseguito impostando la ItemsLayout proprietà su un LinearItemsLayout oggetto , specificando il membro di Horizontal ItemsLayoutOrientation enumerazione come valore della Orientation proprietà:

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

Il codice C# equivalente è il seguente:

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

In questo modo si ottiene un elenco di righe singolo, che aumenta orizzontalmente man mano che vengono aggiunti nuovi elementi:

Screenshot di un layout elenco orizzontale CollectionView, in iOS e Android

Griglia verticale

In XAML un CollectionView oggetto può visualizzare gli elementi in una griglia verticale impostandone la ItemsLayout proprietà su 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>

In alternativa, questo layout può essere eseguito impostando la ItemsLayout proprietà su un GridItemsLayout oggetto la cui Orientation proprietà è impostata su Vertical:

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

Il codice C# equivalente è il seguente:

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

Per impostazione predefinita, un verticale GridItemsLayout visualizzerà gli elementi in una singola colonna. Tuttavia, in questo esempio la GridItemsLayout.Span proprietà viene impostata su 2. Ciò comporta una griglia a due colonne, che aumenta verticalmente man mano che vengono aggiunti nuovi elementi:

Screenshot di un layout griglia verticale CollectionView in iOS e Android

Griglia orizzontale

In XAML un CollectionView oggetto può visualizzare gli elementi in una griglia orizzontale impostandone la ItemsLayout proprietà su 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>

In alternativa, questo layout può essere eseguito impostando la ItemsLayout proprietà su un GridItemsLayout oggetto la cui Orientation proprietà è impostata su Horizontal:

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

Il codice C# equivalente è il seguente:

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

Per impostazione predefinita, un oggetto orizzontale GridItemsLayout visualizzerà gli elementi in una singola riga. Tuttavia, in questo esempio la GridItemsLayout.Span proprietà viene impostata su 4. Ciò comporta una griglia a quattro righe, che aumenta orizzontalmente man mano che vengono aggiunti nuovi elementi:

Screenshot di un layout orizzontale di CollectionView, in iOS e Android

Intestazioni e piè di pagina

CollectionView può presentare un'intestazione e un piè di pagina che scorrono con gli elementi nell'elenco. L'intestazione e il piè di pagina possono essere stringhe, viste o DataTemplate oggetti.

CollectionView definisce le proprietà seguenti per specificare l'intestazione e il piè di pagina:

  • Header, di tipo object, specifica la stringa, l'associazione o la vista che verrà visualizzata all'inizio dell'elenco.
  • HeaderTemplate, di tipo DataTemplate, specifica l'oggetto DataTemplate da utilizzare per formattare l'oggetto Header.
  • Footer, di tipo object, specifica la stringa, l'associazione o la vista che verrà visualizzata alla fine dell'elenco.
  • FooterTemplate, di tipo DataTemplate, specifica l'oggetto DataTemplate da utilizzare per formattare l'oggetto Footer.

Queste proprietà sono supportate da BindableProperty oggetti , il che significa che le proprietà possono essere destinazioni di data binding.

Quando un'intestazione viene aggiunta a un layout che cresce orizzontalmente, da sinistra a destra, l'intestazione viene visualizzata a sinistra dell'elenco. Analogamente, quando un piè di pagina viene aggiunto a un layout che cresce orizzontalmente, da sinistra a destra, il piè di pagina viene visualizzato a destra dell'elenco.

Le Header proprietà e Footer possono essere impostate su string valori, come illustrato nell'esempio seguente:

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

Il codice C# equivalente è il seguente:

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

Questo codice genera gli screenshot seguenti, con l'intestazione mostrata nello screenshot di iOS e il piè di pagina mostrato nello screenshot di Android:

Screenshot di un'intestazione e di un piè di pagina della stringa CollectionView in iOS e Android

Le Header proprietà e Footer possono essere impostate su una visualizzazione. Può trattarsi di una singola visualizzazione o di una visualizzazione che contiene più visualizzazioni figlio. Nell'esempio seguente vengono illustrate le Header proprietà e Footer ognuna di esse impostata su un StackLayout oggetto che contiene un Label oggetto :

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

Il codice C# equivalente è il seguente:

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");

Questo codice genera gli screenshot seguenti, con l'intestazione mostrata nello screenshot di iOS e il piè di pagina mostrato nello screenshot di Android:

Screenshot di un'intestazione e di un piè di pagina CollectionView usando visualizzazioni in iOS e Android

Le HeaderTemplate proprietà e FooterTemplate possono essere impostate su DataTemplate oggetti utilizzati per formattare l'intestazione e il piè di pagina. In questo scenario, le Header proprietà e Footer devono essere associate all'origine corrente per applicare i modelli, come illustrato nell'esempio seguente:

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

Il codice C# equivalente è il seguente:

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");

Questo codice genera gli screenshot seguenti, con l'intestazione mostrata nello screenshot di iOS e il piè di pagina mostrato nello screenshot di Android:

Screenshot di un'intestazione e di un piè di pagina CollectionView usando modelli, in iOS e Android

Spaziatura degli elementi

Per impostazione predefinita, non vi è spazio tra ogni elemento in un oggetto CollectionView. Questo comportamento può essere modificato impostando le proprietà nel layout degli elementi utilizzato da CollectionView.

Quando un CollectionView oggetto imposta la proprietà ItemsLayout su un LinearItemsLayout oggetto , la LinearItemsLayout.ItemSpacing proprietà può essere impostata su un double valore che rappresenta lo spazio tra gli elementi:

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

Nota

La LinearItemsLayout.ItemSpacing proprietà dispone di un set di callback di convalida, che garantisce che il valore della proprietà sia sempre maggiore o uguale a 0.

Il codice C# equivalente è il seguente:

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

Questo codice genera un elenco di colonne singole verticale, con una spaziatura di 20 tra gli elementi:

Screenshot di Un controllo CollectionView con spaziatura degli elementi in iOS e Android

Quando un CollectionView oggetto imposta la proprietà ItemsLayout su un GridItemsLayout oggetto , le GridItemsLayout.VerticalItemSpacing proprietà e GridItemsLayout.HorizontalItemSpacing possono essere impostate su double valori che rappresentano lo spazio vuoto verticalmente e orizzontalmente tra gli elementi:

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

Nota

Per le GridItemsLayout.VerticalItemSpacing proprietà e GridItemsLayout.HorizontalItemSpacing sono impostati callback di convalida, che assicurano che i valori delle proprietà siano sempre maggiori o uguali a 0.

Il codice C# equivalente è il seguente:

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

Questo codice genera una griglia a due colonne verticale, con una spaziatura verticale di 20 tra gli elementi e una spaziatura orizzontale di 30 tra gli elementi:

Screenshot di un oggetto CollectionView con spaziatura degli elementi in Android

Ridimensionamento degli elementi

Per impostazione predefinita, ogni elemento di un CollectionView oggetto viene misurato e ridimensionato singolarmente, purché gli elementi dell'interfaccia utente in DataTemplate non specifichino dimensioni fisse. Questo comportamento, che può essere modificato, viene specificato dal valore della CollectionView.ItemSizingStrategy proprietà. Questo valore della proprietà può essere impostato su uno dei membri dell'enumerazione ItemSizingStrategy :

  • MeasureAllItems – ogni elemento viene misurato singolarmente. Questo è il valore predefinito.
  • MeasureFirstItem – viene misurato solo il primo elemento, con tutti gli elementi successivi con le stesse dimensioni del primo elemento.

Importante

La MeasureFirstItem strategia di dimensionamento comporterà un aumento delle prestazioni quando viene usata in situazioni in cui le dimensioni dell'elemento devono essere uniformi in tutti gli elementi.

Nell'esempio di codice seguente viene illustrata l'impostazione della ItemSizingStrategy proprietà :

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

Il codice C# equivalente è il seguente:

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

Ridimensionamento dinamico degli elementi

Gli elementi in un CollectionView oggetto possono essere ridimensionati in modo dinamico in fase di esecuzione modificando le proprietà correlate al layout degli elementi all'interno di DataTemplate. L'esempio di codice seguente, ad esempio, modifica le HeightRequest proprietà e WidthRequest di un Image oggetto :

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

Il OnImageTapped gestore eventi viene eseguito in risposta a un Image oggetto toccato e modifica le dimensioni dell'immagine in modo che sia più facile da visualizzare:

Screenshot di Un controllo CollectionView con ridimensionamento dinamico degli elementi in iOS e Android

Layout da destra a sinistra

CollectionView può eseguire il layout del contenuto in una direzione del flusso da destra a sinistra impostandone la FlowDirection proprietà su RightToLeft. Tuttavia, la FlowDirection proprietà deve essere impostata idealmente in un layout di pagina o radice, causando la risposta di tutti gli elementi all'interno della pagina o del layout radice alla direzione del flusso:

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

Il valore predefinito FlowDirection per un elemento con un elemento padre è MatchParent. Pertanto, CollectionView eredita il valore della FlowDirection proprietà da StackLayout, che a sua volta eredita il valore della FlowDirection ContentPageproprietà da . Ciò comporta il layout da destra a sinistra illustrato negli screenshot seguenti:

Screenshot di un layout di elenco verticale da destra a sinistra di CollectionView in iOS e Android

Per altre informazioni sulla direzione del flusso, vedere Localizzazione da destra a sinistra.