Xamarin.Forms CollectionView のグループ化
大規模なデータ セットは、継続的にスクロールするリストで表示されると扱いにくくなることがよくあります。 このシナリオでは、データをグループにまとめることで、データ間の移動が容易になり、ユーザー エクスペリエンスが向上します。
CollectionView
は、グループ化されたデータの表示をサポートし、表示方法を制御する次のプロパティを定義します。
bool
型のIsGrouped
は、基になるデータをグループに表示するかどうかを示します。 このプロパティの既定値はfalse
です。DataTemplate
型のGroupHeaderTemplate
は、各グループのヘッダーに使用するテンプレートです。DataTemplate
型のGroupFooterTemplate
は、各グループのフッターに使用するテンプレートです。
これらのプロパティはすべて、BindableProperty
オブジェクトを基盤としています。つまり、プロパティをデータ バインディングの対象にすることができます。
次のスクリーンショットは、グループ化されたデータを表示する CollectionView
を示しています。
データ テンプレートの詳細については、「Xamarin.Forms のデータ テンプレート」を参照してください。
データをグループ化する
データは、表示する前にグループ化する必要があります。 これは、各グループが項目のリストであるグループのリストを作成することによって実現できます。 グループのリストは IEnumerable<T>
コレクションである必要があり、T
では、次の 2 つのデータが定義されます。
- グループ名。
- グループに属する項目を定義する
IEnumerable
コレクション。
したがって、データをグループ化するプロセスは次のとおりです。
- 1 つの項目をモデル化する型を作成します。
- 1 つの項目グループをモデル化する型を作成します。
IEnumerable<T>
コレクションを作成します。T
は、項目の 1 つのグループをモデル化する型です。 したがって、このコレクションはグループ化されたデータを格納するグループのコレクションです。IEnumerable<T>
コレクションにデータを追加します。
例
データをグループ化する場合、最初の手順は、1 つの項目をモデル化する型を作成することです。 次の例は、サンプル アプリケーションの Animal
クラスを示しています。
public class Animal
{
public string Name { get; set; }
public string Location { get; set; }
public string Details { get; set; }
public string ImageUrl { get; set; }
}
Animal
クラスは、1 つの項目をモデル化します。 その後、項目のグループをモデル化する型を作成できます。 次の例は、サンプル アプリケーションの AnimalGroup
クラスを示しています。
public class AnimalGroup : List<Animal>
{
public string Name { get; private set; }
public AnimalGroup(string name, List<Animal> animals) : base(animals)
{
Name = name;
}
}
AnimalGroup
クラスは List<T>
クラスを継承し、グループ名を表す Name
プロパティを追加します。
その後、グループの IEnumerable<T>
コレクションを作成できます。
public List<AnimalGroup> Animals { get; private set; } = new List<AnimalGroup>();
このコードでは、コレクション内の各項目が AnimalGroup
オブジェクトである、Animals
という名前のコレクションを定義します。 各 AnimalGroup
オブジェクトは、名前と、グループ内の Animal
オブジェクトを定義する List<Animal>
コレクションで構成されます。
その後、グループ化されたデータを Animals
コレクションに追加できます。
Animals.Add(new AnimalGroup("Bears", new List<Animal>
{
new Animal
{
Name = "American Black Bear",
Location = "North America",
Details = "Details about the bear go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/0/08/01_Schwarzbär.jpg"
},
new Animal
{
Name = "Asian Black Bear",
Location = "Asia",
Details = "Details about the bear go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/b/b7/Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG/180px-Ursus_thibetanus_3_%28Wroclaw_zoo%29.JPG"
},
// ...
}));
Animals.Add(new AnimalGroup("Monkeys", new List<Animal>
{
new Animal
{
Name = "Baboon",
Location = "Africa & Asia",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/fc/Papio_anubis_%28Serengeti%2C_2009%29.jpg/200px-Papio_anubis_%28Serengeti%2C_2009%29.jpg"
},
new Animal
{
Name = "Capuchin Monkey",
Location = "Central & South America",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/4/40/Capuchin_Costa_Rica.jpg/200px-Capuchin_Costa_Rica.jpg"
},
new Animal
{
Name = "Blue Monkey",
Location = "Central and East Africa",
Details = "Details about the monkey go here.",
ImageUrl = "https://upload.wikimedia.org/wikipedia/commons/thumb/8/83/BlueMonkey.jpg/220px-BlueMonkey.jpg"
},
// ...
}));
このコードは、Animals
コレクション内に 2 つのグループを作成します。 1 つ目の AnimalGroup
は Bears
という名前が付けられ、クマの詳細の List<Animal>
コレクションが含まれています。 2 つ目 AnimalGroup
は Monkeys
という名前が付けられ、サルの詳細の List<Animal>
コレクションが含まれています。
グループ化されたデータを表示する
IsGrouped
プロパティを true
に設定することで、データが正しくグループ化されている場合は、CollectionView
にはグループ化されたデータが表示されます。
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
...
<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
{
IsGrouped = true
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
// ...
CollectionView
内の各項目の外観は、CollectionView.ItemTemplate
プロパティを DataTemplate
に設定することによって定義されます。 詳細については、「項目の外観を定義する」をご覧ください。
Note
既定で、CollectionView
にはグループ ヘッダーとフッターにグループ名が表示されます。 この動作は、グループ ヘッダーとグループ フッターをカスタマイズすることで変更できます。
グループ ヘッダーをカスタマイズする
各グループ ヘッダーの外観は、CollectionView.GroupHeaderTemplate
プロパティを DataTemplate
に設定することでカスタマイズできます。
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true">
...
<CollectionView.GroupHeaderTemplate>
<DataTemplate>
<Label Text="{Binding Name}"
BackgroundColor="LightGray"
FontSize="Large"
FontAttributes="Bold" />
</DataTemplate>
</CollectionView.GroupHeaderTemplate>
</CollectionView>
この例では、各グループ ヘッダーは、グループ名を表示する Label
に設定されており、その他の外観プロパティが設定されています。 次のスクリーンショットは、カスタマイズされたグループ ヘッダーを示しています。
グループ フッターをカスタマイズする
各グループ フッターの外観は、CollectionView.GroupFooterTemplate
プロパティを DataTemplate
に設定することでカスタマイズできます。
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true">
...
<CollectionView.GroupFooterTemplate>
<DataTemplate>
<Label Text="{Binding Count, StringFormat='Total animals: {0:D}'}"
Margin="0,0,0,10" />
</DataTemplate>
</CollectionView.GroupFooterTemplate>
</CollectionView>
この例では、各グループ フッターは、グループ内の項目数を表示する Label
に設定されています。 次のスクリーンショットは、カスタマイズされたグループ フッターを示しています。
空のグループ
CollectionView
がグループ化されたデータを表示すると、空のグループが表示されます。 このようなグループは、グループヘッダーとフッターと共に表示され、グループが空であることを示します。 次のスクリーンショットは、空のグループを示しています。
Note
iOS 10以前では、空のグループのグループヘッダーとフッターがすべて CollectionView
の上部に表示されることがあります。
テンプレートのないグループ
CollectionView
は、CollectionView.ItemTemplate
プロパティを DataTemplate
に設定しなくても、正しくグループ化されたデータを表示できます。
<CollectionView ItemsSource="{Binding Animals}"
IsGrouped="true" />
このシナリオでは、1 つの項目をモデル化する型と、1 つの項目グループをモデル化する型の ToString
メソッドを上書きすることで、意味のあるデータを表示できます。