GridViewにグループ化された項目を表示するには

CollectionViewSource

GridViewはグループ化された項目を表示することができます。

WindowsストアアプリのGridVewテンプレートなどはグループ化された項目が表示できるようになっています。
44

しかし通常のコレクションをItemsSourceに入れてもグループ化は表現できません。
そこでCollectionViewSourceというものを使います。
CollectionViewSourceはグループ化されたコレクションのバインドをサポートし、グループ化されたコンテンツを表示するときによく使われます。

グループ化されたコレクションを作る

今回はSampleItemというアイテムをSmapleGroupクラスでグループ化し、そのグループのコレクションをMainViewModelが持つという形のサンプルデータを作ります。
11

データの最小単位のアイテムです。
タイトルとテキストのメンバを所持します。

/// <summary>
/// グループ内のアイテム
/// </summary>
public class SampleItem
{
    //アイテムタイトル
    public string Title { get; set; }
    //アイテムテキスト
    public string Text { get; set; }
    public SampleItem()
    {

    }
}

SmapleItemのコレクションを持つグループです。
グループタイトルというメンバを持ちます。

/// <summary>
/// データのグループ
/// </summary>
public class SampleItemGroup
{
    //グループタイトル
    public string GroupTitle { get; set; } 

    //グループ内のアイテム
    public ObservableCollection<SampleItem> Items { get; set; } 
    public SampleItemGroup()
    {
        Items=new ObservableCollection<SampleItem>();
    }
}

MainVeiwModelです。SmapleItemGroupのコレクションをもち、コンストラクタでサンプルデータを入れています。
このmainViewModelが直接PageのDataContextに入ります。

public class MainViewModel
{
    //データのグループ
    public ObservableCollection<SampleItemGroup> Groups { get; set; } 
    public MainViewModel()
    {
        Groups=new ObservableCollection<SampleItemGroup>();
        

        //サンプルデータを入れる
        var group1 = new SampleItemGroup();
        group1.GroupTitle = "グループ1";
        group1.Items.Add(new SampleItem
        {
            Title = "タイトル1-1",
            Text = "テキスト1-1"
        });
        group1.Items.Add(new SampleItem
        {
            Title = "タイトル1-2",
            Text = "テキスト1-2"
        });
        var group2=new SampleItemGroup();
        group2.GroupTitle = "グループ2";
        group2.Items.Add(new SampleItem
        {
            Title = "タイトル2-1",
            Text = "テキスト2-1"
        });
        group2.Items.Add(new SampleItem
        {
            Title = "タイトル2-2",
            Text = "テキスト2-2"
        });
        group2.Items.Add(new SampleItem
        {
            Title = "タイトル2-3",
            Text = "テキスト2-3"
        });

        var group3 = new SampleItemGroup();
        group3.GroupTitle = "グループ3";
        group3.Items.Add(new SampleItem
        {
            Title = "タイトル3-1",
            Text = "テキスト3-1"
        });
        Groups.Add(group1);
        Groups.Add(group2);
        Groups.Add(group3);
    }
}

Viewを作る

続いてXAMLです。
PageのリソースにCollectionViewSource型のリソースを作ります。
SourceプロパティにはMainViewModelのGroupsコレクションとバインドをし、
ItemsPathプロパティにはSampleItemGroup内にあるItemsコレクションの名前を指定します。
ItemsPathはBindingでは無いので注意しましょう。
IsSourceGroupedをTrueにしないとグループ化されません。

<Page.Resources>

    <CollectionViewSource x:Key="sampleGroupSource" Source="{Binding Groups}" ItemsPath="Items" IsSourceGrouped="True" />

</Page.Resources>

続いてGridViewです。
ItemsSourceには先ほど作成したCollectionViewSourceとのバインドを行います。

ItemTemplateでは実際のアイテム1つのテンプレートを指定します。
SmapleItemがDataContextに入るのでTitleとTextをバインドさせます。

GroupStyleではHeaderTemplateを編集し、
グループタイトルがButtonに表示されるようにします。
SampleItemGroupがDataContextに入るのでGroupTitleとバインドをおこないます。

<GridView Grid.Row="1" ItemsSource="{Binding Source={StaticResource sampleGroupSource}}">
    <GridView.ItemTemplate>
        <DataTemplate>
            <StackPanel Width="250" Height="250">
                <TextBlock Text="{Binding Title}" />
                <TextBlock Text="{Binding Text}" />
            </StackPanel>
        </DataTemplate>
    </GridView.ItemTemplate>
    <GridView.GroupStyle>
        <GroupStyle>
            <GroupStyle.HeaderTemplate>
                <DataTemplate>
                    <Button Content="{Binding GroupTitle}" />
                </DataTemplate>
            </GroupStyle.HeaderTemplate>
        </GroupStyle>
    </GridView.GroupStyle>
    
</GridView>

最後にPageのDataContextにMainViewModelを入れたら完成です。

<Page.DataContext>
    <local:MainViewModel />
</Page.DataContext>

グループ化されたコレクションがGridViewにグループ化されて表示されています。
43

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください