CollectionView は、レイアウトを制御する次のプロパティを定義します:
IItemsLayout型のItemsLayoutは、使用するレイアウトを指定します。ItemSizingStrategy型のItemSizingStrategyは、使用する項目測定法を指定します。
これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティをデータ バインディングの対象にすることができます。
既定では、CollectionView は項目を縦向きリストで表示します。 ただし、次のいずれかのレイアウトも使用できます。
- 縦向きリスト – 新しい項目が追加されると縦に広がる 1 列のリスト。
- 横向きリスト – 新しい項目が追加されると横に広がる 1 行のリスト。
- 縦向きグリッド – 新しい項目が追加されると縦に広がる複数列のグリッド。
- 横向きグリッド – 新しい項目が追加されると横に広がる複数行のグリッド。
これらのレイアウトは、ItemsLayout プロパティを ItemsLayout クラスから派生するクラスに設定することで指定できます。 このクラスでは、次のプロパティが定義されています。
ItemsLayoutOrientation型のOrientationは、項目が追加されたときにCollectionViewが広がる方向を指定します。SnapPointsAlignmentは、SnapPointsAlignment型で、スナップ ポイントを項目に合わせる方法を指定します。SnapPointsTypeは、SnapPointsType型で、スクロール時のスナップ ポイントの動作を指定します。
これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティをデータ バインディングの対象にすることができます。 スナップポイントの詳細については、「Xamarin.FormsCollectionView スクロール ガイド」の「スナップ ポイント」を参照してください。
ItemsLayoutOrientation 列挙型には、次のメンバーが定義されています。
Verticalは、項目が追加されるとCollectionViewが縦に広がることを示します。Horizontalは、項目が追加されるとCollectionViewが横に広がることを示します。
LinearItemsLayout クラスは ItemsLayout クラスを継承し、各項目の周囲の空のスペースを表す double 型 の ItemSpacing プロパティを定義します。 このプロパティの既定値は 0 であり、その値は常に 0 以上である必要があります。 LinearItemsLayout クラスでは、静的な Vertical メンバーと Horizontal メンバーも定義されます。 これらのメンバーを使用すると、縦向きまたは横向きのリストをそれぞれ作成できます。 または、ItemsLayoutOrientation 列挙メンバーを引数として指定して、LinearItemsLayout オブジェクトを作成することもできます。
GridItemsLayout クラスは ItemsLayout クラスを継承し、次のプロパティを定義します。
- 各項目の周囲の縦方向の空きスペースを表す、
double型のVerticalItemSpacing。 このプロパティの既定値は 0 であり、その値は常に 0 以上である必要があります。 - 各項目の周囲の横方向の空きスペースを表す、
double型のHorizontalItemSpacing。 このプロパティの既定値は 0 であり、その値は常に 0 以上である必要があります。 - グリッドに表示する列数または行数を表す、
int型のSpan。 このプロパティの既定値は 1 であり、その値は常に 1 以上である必要があります。
これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティをデータ バインディングの対象にすることができます。
Note
CollectionView では、ネイティブ レイアウト エンジンを使用してレイアウトを実行します。
バーティカル リスト
既定では、CollectionView は項目を縦向きリストのレイアウトで表示します。 そのため、そのレイアウトを使用するように ItemsLayout プロパティを設定する必要はありません。
<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>
ただし、完全を期すために、XAML で ItemsLayout プロパティを VerticalList に設定することで、項目を縦向きリストに表示するように CollectionView を設定することもできます。
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="VerticalList">
...
</CollectionView>
または、これは次のように、ItemsLayout プロパティを LinearItemsLayout オブジェクトに設定し、Vertical ItemsLayoutOrientation 列挙メンバーを Orientation プロパティ値として指定することでも実現できます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical" />
</CollectionView.ItemsLayout>
...
</CollectionView>
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Vertical
};
これにより、新しい項目が追加されると縦に広がる、1 列のリストが作成されます。
横向きリスト
XAML で ItemsLayout プロパティを HorizontalList に設定することで、CollectionView で項目を横向きリストに表示できます。
<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>
または次のように、ItemsLayout プロパティを LinearItemsLayout オブジェクトに設定し、Horizontal ItemsLayoutOrientation 列挙メンバーを Orientation プロパティ値として指定することでも、このレイアウトを実現できます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Horizontal" />
</CollectionView.ItemsLayout>
...
</CollectionView>
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = LinearItemsLayout.Horizontal
};
これにより、新しい項目が追加されると横に広がる、1 行リストが作成されます。
垂直グリッド
XAML で ItemsLayout プロパティを VerticalGrid に設定することで、CollectionView で項目を縦向きグリッドに表示できます。
<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>
または、Orientation プロパティが Vertical に設定されている GridItemsLayout オブジェクトに ItemsLayout プロパティを設定することで、このレイアウトを実現することもできます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2" />
</CollectionView.ItemsLayout>
...
</CollectionView>
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
};
既定では、縦向き GridItemsLayout の項目は 1 列に表示されます。 この例では、GridItemsLayout.Span プロパティを 2 に設定しています。 これにより、2 列のグリッドが作成され、新しい項目が追加されると縦に広がります。
水平グリッド
XAML で ItemsLayout プロパティを HorizontalGrid に設定することで、CollectionView で項目を横向きグリッドに表示できます。
<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>
または、Orientation プロパティが Horizontal に設定されている GridItemsLayout オブジェクトに ItemsLayout プロパティを設定することで、このレイアウトを実現することもできます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Horizontal"
Span="4" />
</CollectionView.ItemsLayout>
...
</CollectionView>
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(4, ItemsLayoutOrientation.Horizontal)
};
既定では、横向き GridItemsLayout の項目は 1 行に表示されます。 この例では、GridItemsLayout.Span プロパティを 4 に設定しています。 これにより、4 行のグリッドが作成され、新しい項目が追加されると横に広がります。
ヘッダーとフッター
CollectionView では、リスト内の項目と共にスクロールするヘッダーとフッターを表示できます。 ヘッダーとフッターには、文字列、ビュー、DataTemplate オブジェクトを指定できます。
CollectionView は、ヘッダーとフッターを指定するための次のプロパティを定義します。
object型のHeaderは、リストの先頭に表示される文字列、バインド、またはビューを指定します。DataTemplate型のHeaderTemplateは、Headerの書式を設定するために使用するDataTemplateを指定します。object型のFooterは、リストの末尾に表示される文字列、バインド、またはビューを指定します。DataTemplate型のFooterTemplateは、Footerの書式を設定するために使用するDataTemplateを指定します。
これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティをデータ バインディングの対象にすることができます。
左から右へ横に広がるレイアウトにヘッダーを追加すると、ヘッダーはリストの左側に表示されます。 同様に、左から右へ横に広がるレイアウトにフッターを追加すると、フッターはリストの右側に表示されます。
ヘッダーとフッターに文字列を表示する
次の例に示すように、Header プロパティと Footer プロパティは、string 値に設定することもできます。
<CollectionView ItemsSource="{Binding Monkeys}"
Header="Monkeys"
Footer="2019">
...
</CollectionView>
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
Header = "Monkeys",
Footer = "2019"
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");
このコードの結果は次のスクリーンショットのようになり、ヘッダーは iOS のスクリーンショットに、フッターは Android のスクリーンショットに表示されます。
ヘッダーとフッターにビューを表示する
Header プロパティと Footer プロパティには、それぞれビューを設定できます。 1 つのビュー、または複数の子ビューを含むビューを指定できます。 次の例は、Header プロパティと Footer プロパティがそれぞれ、Label オブジェクトを含む StackLayout オブジェクトに設定されていることを示しています。
<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>
同等の C# コードを次に示します。
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");
このコードの結果は次のスクリーンショットのようになり、ヘッダーは iOS のスクリーンショットに、フッターは Android のスクリーンショットに表示されます。
テンプレート化されたヘッダーとフッターを表示する
HeaderTemplate プロパティと FooterTemplate プロパティを DataTemplate オブジェクトに設定すると、ヘッダーとフッターの書式設定に使用できます。 このシナリオでは、以下の例に示すように、テンプレートを適用するためには、Header プロパティと Footer プロパティが現在のソースにバインドされている必要があります。
<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>
同等の C# コードを次に示します。
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");
このコードの結果は次のスクリーンショットのようになり、ヘッダーは iOS のスクリーンショットに、フッターは Android のスクリーンショットに表示されます。
項目の間隔
既定では、CollectionView 内の各項目の間にスペースはありません。 この動作は、CollectionView で使用される項目レイアウトのプロパティを設定することで変更できます。
CollectionView でその ItemsLayout プロパティを LinearItemsLayout オブジェクトに設定すると、項目間のスペースを表す double 値を LinearItemsLayout.ItemSpacing プロパティに設定できます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"
ItemSpacing="20" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Note
LinearItemsLayout.ItemSpacing プロパティには、プロパティの値が常に 0 以上であることを確認できる、検証コールバック セットがあります。
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
{
ItemSpacing = 20
}
};
このコードでは、項目間の間隔が 20 の垂直方向の縦 1 列のいリストになります:
CollectionView で ItemsLayout プロパティを GridItemsLayout オブジェクトに設定すると、項目間の縦と横の空きスペースを表す double 値を GridItemsLayout.VerticalItemSpacing プロパティと GridItemsLayout.HorizontalItemSpacing プロパティに設定できます。
<CollectionView ItemsSource="{Binding Monkeys}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical"
Span="2"
VerticalItemSpacing="20"
HorizontalItemSpacing="30" />
</CollectionView.ItemsLayout>
...
</CollectionView>
Note
GridItemsLayout.VerticalItemSpacing プロパティと GridItemsLayout.HorizontalItemSpacing プロパティには検証コールバックが設定されており、プロパティの値が常に 0 以上であることを確認します。
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemsLayout = new GridItemsLayout(2, ItemsLayoutOrientation.Vertical)
{
VerticalItemSpacing = 20,
HorizontalItemSpacing = 30
}
};
このコードにより、項目間の縦方向の間隔が 20、項目間の水平方向の間隔が 30 の縦 2 列のグリッドが作成されます:
項目のサイズ
既定では、DataTemplate の UI 要素が固定サイズを指定されていない限り、CollectionView の各項目は個別に測定され、サイズが設定されます。 この動作は変更でき、CollectionView.ItemSizingStrategy プロパティ値で指定できます。 このプロパティの値は、ItemSizingStrategy 列挙要素に 1 つに設定されます。
MeasureAllItems– 各項目は個別に測定されます。 これが既定値です。MeasureFirstItem– 最初の項目のみが測定され、後続のすべての項目に最初の項目と同じサイズが与えられます。
重要
MeasureFirstItem の方法でサイズを設定すると、項目のサイズがすべての項目で均一な状況でパフォーマンスが向上します。
次のコード例では、ItemSizingStrategy プロパティの設定を示します。
<CollectionView ...
ItemSizingStrategy="MeasureFirstItem">
...
</CollectionView>
同等の C# コードを次に示します。
CollectionView collectionView = new CollectionView
{
...
ItemSizingStrategy = ItemSizingStrategy.MeasureFirstItem
};
項目の動的なサイズ変更
DataTemplate 内の要素の レイアウト関連プロパティを変更することで、CollectionView の項目のサイズを実行時に動的に変更できます。 たとえば、次のコード例では、Image オブジェクトの HeightRequest プロパティと WidthRequest プロパティを変更します。
void OnImageTapped(object sender, EventArgs e)
{
Image image = sender as Image;
image.HeightRequest = image.WidthRequest = image.HeightRequest.Equals(60) ? 100 : 60;
}
OnImageTapped イベント ハンドラーはタップされている Image オブジェクトに応答して実行され、画像のサイズを変更して表示しやすくします。
右から左へのレイアウト
CollectionView を使用すると、FlowDirection プロパティを RightToLeft に設定することで、コンテンツを右から左へのフロー方向にレイアウトできます。 ただし、FlowDirection プロパティは、ページまたはルート レイアウトに設定するのが理想的です。これにより、そのページまたはルート レイアウト内のすべての要素について、フローの方向が定まります。
<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>
親を持つ要素の既定の FlowDirection は MatchParent です。 そのため、CollectionView は StackLayout から FlowDirection プロパティ値を継承し、さらに ContentPage から FlowDirection プロパティ値を継承します。 これで、次のスクリーンショットに示すような右から左のレイアウトになります:
フローの向きについて詳しくは、「右から左へのローカライズ」をご覧ください。










