次の方法で共有


Xamarin.Forms CollectionView のグループ化

大規模なデータ セットは、継続的にスクロールするリストで表示されると扱いにくくなることがよくあります。 このシナリオでは、データをグループにまとめることで、データ間の移動が容易になり、ユーザー エクスペリエンスが向上します。

CollectionView は、グループ化されたデータの表示をサポートし、表示方法を制御する次のプロパティを定義します。

  • bool 型の IsGrouped は、基になるデータをグループに表示するかどうかを示します。 このプロパティの既定値は false です。
  • DataTemplate 型の GroupHeaderTemplate は、各グループのヘッダーに使用するテンプレートです。
  • DataTemplate 型の GroupFooterTemplate は、各グループのフッターに使用するテンプレートです。

これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティをデータ バインディングの対象にすることができます。

次のスクリーンショットは、グループ化されたデータを表示する CollectionView を示しています。

iOS および Android 上の 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 つ目の AnimalGroupBears という名前が付けられ、クマの詳細の List<Animal> コレクションが含まれています。 2 つ目 AnimalGroupMonkeys という名前が付けられ、サルの詳細の 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 に設定されており、その他の外観プロパティが設定されています。 次のスクリーンショットは、カスタマイズされたグループ ヘッダーを示しています。

iOS および Android 上の CollectionView のカスタマイズされたグループ ヘッダーのスクリーンショット

各グループ フッターの外観は、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 に設定されています。 次のスクリーンショットは、カスタマイズされたグループ フッターを示しています。

iOS および Android 上の CollectionView のカスタマイズされたグループ フッターのスクリーンショット

空のグループ

CollectionView がグループ化されたデータを表示すると、空のグループが表示されます。 このようなグループは、グループヘッダーとフッターと共に表示され、グループが空であることを示します。 次のスクリーンショットは、空のグループを示しています。

iOS および Android 上の CollectionView の空のグループのスクリーンショット

Note

iOS 10以前では、空のグループのグループヘッダーとフッターがすべて CollectionView の上部に表示されることがあります。

テンプレートのないグループ

CollectionView は、CollectionView.ItemTemplate プロパティを DataTemplate に設定しなくても、正しくグループ化されたデータを表示できます。

<CollectionView ItemsSource="{Binding Animals}"
                IsGrouped="true" />

このシナリオでは、1 つの項目をモデル化する型と、1 つの項目グループをモデル化する型の ToString メソッドを上書きすることで、意味のあるデータを表示できます。