Xamarin.Forms CollectionView データ

サンプルのダウンロードサンプルのダウンロード

CollectionView には、表示するデータとその外観を定義する次のプロパティが含まれています。

  • ItemsSourceIEnumerableの は、表示する項目のコレクションを指定し、既定値は nullです。
  • ItemTemplateDataTemplateの は、表示する項目のコレクション内の各項目に適用するテンプレートを指定します。

これらのプロパティはオブジェクトによって BindableProperty サポートされます。つまり、プロパティはデータ バインディングのターゲットにすることができます。

注意

CollectionView は、 ItemsUpdatingScrollMode 新しい項目が追加されたときの のスクロール動作を CollectionView 表す プロパティを定義します。 このプロパティの詳細については、「 新しい項目が追加されたときにスクロール位置を制御する」を参照してください。

CollectionView では、ユーザーがスクロールするにつれて増分データ仮想化がサポートされます。 詳細については、「データの 増分読み込み」を参照してください。

CollectionView にデータを設定する

CollectionViewプロパティを を実装IEnumerableする任意のコレクションに設定ItemsSourceすることで、 にデータが設定されます。 既定では、 CollectionView は項目を垂直リストに表示します。

重要

CollectionView基になるコレクションで項目が追加、削除、または変更されるときに を更新する必要がある場合、基になるコレクションは、 などのObservableCollectionプロパティ変更通知をIEnumerable送信するコレクションである必要があります。

CollectionView データ バインディングを使用して、その ItemsSource プロパティをコレクションにバインドすることで、データを IEnumerable 設定できます。 XAML では、これはマークアップ拡張機能を使用して Binding 実現されます。

<CollectionView ItemsSource="{Binding Monkeys}" />

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

この例では、プロパティ データは ItemsSource 接続された Monkeys ビューモデルの プロパティにバインドされます。

注意

コンパイル済みバインドを有効にして、アプリケーションのデータ バインディングのパフォーマンスを Xamarin.Forms 向上させることができます。 詳しくは、「コンパイル済みのバインド」を参照してください。

レイアウトを変更CollectionViewする方法については、「CollectionView レイアウト」を参照してくださいXamarin.Forms。 内の各項目の外観を定義する方法については、「項目の外観をCollectionView定義する」を参照してください。 データ バインディングの詳細については、「Xamarin.Forms のデータ バインディング」を参照してください。

警告

CollectionView は、UI スレッドから更新された場合 ItemsSource に例外をスローします。

アイテムの外観を定義する

CollectionView の各項目の外観は、 プロパティを CollectionView.ItemTemplateDataTemplate設定することで定義できます。

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

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

collectionView.ItemTemplate = new DataTemplate(() =>
{
    Grid grid = new Grid { Padding = 10 };
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
    grid.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });

    Image image = new Image { Aspect = Aspect.AspectFill, HeightRequest = 60, WidthRequest = 60 };
    image.SetBinding(Image.SourceProperty, "ImageUrl");

    Label nameLabel = new Label { FontAttributes = FontAttributes.Bold };
    nameLabel.SetBinding(Label.TextProperty, "Name");

    Label locationLabel = new Label { FontAttributes = FontAttributes.Italic, VerticalOptions = LayoutOptions.End };
    locationLabel.SetBinding(Label.TextProperty, "Location");

    Grid.SetRowSpan(image, 2);

    grid.Children.Add(image);
    grid.Children.Add(nameLabel, 1, 0);
    grid.Children.Add(locationLabel, 1, 1);

    return grid;
});

DataTemplate 指定された要素は、リスト内の各項目の外観を定義します。 この例では、 内の DataTemplate レイアウトは によって Grid管理されています。 には Grid 、 クラスの Image プロパティにバインドするオブジェクトと 2 つの Label オブジェクトが Monkey 含まれています。

public class Monkey
{
    public string Name { get; set; }
    public string Location { get; set; }
    public string Details { get; set; }
    public string ImageUrl { get; set; }
}

次のスクリーンショットは、リスト内の各項目をテンプレート化した結果を示しています。

CollectionView のスクリーンショット。CollectionView 内の iOS および Android、各項目がテンプレート化されています

データ テンプレートの詳細については、「Xamarin.Forms のデータ テンプレート」を参照してください。

実行時にアイテムの外観を選択する

内の各項目 CollectionView の外観は、 プロパティを オブジェクトに設定 CollectionView.ItemTemplate することで、項目の値に基づいて実行時に DataTemplateSelector 選択できます。

<ContentPage ...
             xmlns:controls="clr-namespace:CollectionViewDemos.Controls">
    <ContentPage.Resources>
        <DataTemplate x:Key="AmericanMonkeyTemplate">
            ...
        </DataTemplate>

        <DataTemplate x:Key="OtherMonkeyTemplate">
            ...
        </DataTemplate>

        <controls:MonkeyDataTemplateSelector x:Key="MonkeySelector"
                                             AmericanMonkey="{StaticResource AmericanMonkeyTemplate}"
                                             OtherMonkey="{StaticResource OtherMonkeyTemplate}" />
    </ContentPage.Resources>

    <CollectionView ItemsSource="{Binding Monkeys}"
                    ItemTemplate="{StaticResource MonkeySelector}" />
</ContentPage>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    ItemTemplate = new MonkeyDataTemplateSelector { ... }
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

プロパティは ItemTemplate オブジェクトに MonkeyDataTemplateSelector 設定されます。 次の例は、MonkeyDataTemplateSelector クラスを示しています。

public class MonkeyDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate AmericanMonkey { get; set; }
    public DataTemplate OtherMonkey { get; set; }

    protected override DataTemplate OnSelectTemplate(object item, BindableObject container)
    {
        return ((Monkey)item).Location.Contains("America") ? AmericanMonkey : OtherMonkey;
    }
}

クラスは MonkeyDataTemplateSelectorAmericanMonkey 異なるデータ テンプレートに設定される プロパティと OtherMonkeyDataTemplate プロパティを定義します。 オーバーライドは OnSelectTemplate テンプレートを AmericanMonkey 返します。このテンプレートでは、サルの名前に "America" が含まれている場合に、サルの名前と場所が teal に表示されます。 サルの名前に "America" が含まれていない場合、 OnSelectTemplate オーバーライドはテンプレートを OtherMonkey 返します。これにより、サルの名前と場所が銀色で表示されます。

の選択 CollectionView ランタイム項目テンプレートの選択のスクリーンショット。iOS および Android

データ テンプレート セレクターの詳細については、「 DataTemplateSelector の Xamarin.Forms 作成」を参照してください。

重要

を使用 CollectionViewする場合は、オブジェクトのルート要素を DataTemplateViewCell設定しないでください。 これにより、セルの概念がないため CollectionView 、例外がスローされます。

コンテキスト メニュー

CollectionView では、 を介した SwipeViewデータ項目のコンテキスト メニューがサポートされています。これにより、スワイプ ジェスチャを使用してコンテキスト メニューが表示されます。 SwipeViewは、コンテンツの項目をラップし、そのコンテンツ項目のコンテキスト メニュー項目を提供するコンテナー コントロールです。 したがって、 のコンテキスト メニューは、ラップするコンテンツSwipeViewSwipeView定義する を作成し、スワイプ ジェスチャによって表示されるコンテキスト メニュー項目を作成することによって実装CollectionViewされます。 これは、 内のデータの各項目の外観を定義する のDataTemplateルート ビューとして を設定SwipeViewすることによって実現されますCollectionView

<CollectionView x:Name="collectionView"
                ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemTemplate>
        <DataTemplate>
            <SwipeView>
                <SwipeView.LeftItems>
                    <SwipeItems>
                        <SwipeItem Text="Favorite"
                                   IconImageSource="favorite.png"
                                   BackgroundColor="LightGreen"
                                   Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.FavoriteCommand}"
                                   CommandParameter="{Binding}" />
                        <SwipeItem Text="Delete"
                                   IconImageSource="delete.png"
                                   BackgroundColor="LightPink"
                                   Command="{Binding Source={x:Reference collectionView}, Path=BindingContext.DeleteCommand}"
                                   CommandParameter="{Binding}" />
                    </SwipeItems>
                </SwipeView.LeftItems>
                <Grid BackgroundColor="White"
                      Padding="10">
                    <!-- Define item appearance -->
                </Grid>
            </SwipeView>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Monkeys");

collectionView.ItemTemplate = new DataTemplate(() =>
{
    // Define item appearance
    Grid grid = new Grid { Padding = 10, BackgroundColor = Color.White };
    // ...

    SwipeView swipeView = new SwipeView();
    SwipeItem favoriteSwipeItem = new SwipeItem
    {
        Text = "Favorite",
        IconImageSource = "favorite.png",
        BackgroundColor = Color.LightGreen
    };
    favoriteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.FavoriteCommand", source: collectionView));
    favoriteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");

    SwipeItem deleteSwipeItem = new SwipeItem
    {
        Text = "Delete",
        IconImageSource = "delete.png",
        BackgroundColor = Color.LightPink
    };
    deleteSwipeItem.SetBinding(MenuItem.CommandProperty, new Binding("BindingContext.DeleteCommand", source: collectionView));
    deleteSwipeItem.SetBinding(MenuItem.CommandParameterProperty, ".");

    swipeView.LeftItems = new SwipeItems { favoriteSwipeItem, deleteSwipeItem };
    swipeView.Content = grid;    
    return swipeView;
});

この例では、 SwipeView コンテンツは Grid 内の各項目の外観を定義する CollectionViewです。 スワイプ項目は、コンテンツに対してアクションを SwipeView 実行するために使用され、コントロールが左側からスワイプされると表示されます。

CollectionView iOS および Android CollectionView の CollectionView コンテキスト メニュー項目のスクリーンショット

SwipeView は 4 つの異なるスワイプ方向をサポートし、オブジェクトが追加される方向コレクションによってスワイプ方向 SwipeItemsSwipeItems 定義されます。 既定では、スワイプ項目はユーザーによってタップされたときに実行されます。 さらに、スワイプ項目が実行されると、スワイプ項目は非表示になり、 SwipeView コンテンツが再表示されます。 ただし、これらの動作は変更できます。

コントロールのSwipeView詳細については、「SwipeView」を参照してくださいXamarin.Forms

引っ張って更新

CollectionView では、 を使用して RefreshViewプルを更新する機能がサポートされています。これにより、アイテムの一覧をプルダウンすることで、表示されるデータを更新できます。 RefreshViewは、子がスクロール可能なコンテンツをサポートしている場合に、その子にプルを提供して更新機能を提供するコンテナー コントロールです。 したがって、更新へのプルは、 の子として設定することによって、 RefreshViewに対CollectionViewして実装されます。

<RefreshView IsRefreshing="{Binding IsRefreshing}"
             Command="{Binding RefreshCommand}">
    <CollectionView ItemsSource="{Binding Animals}">
        ...
    </CollectionView>
</RefreshView>

これに相当する C# コードを次に示します。

RefreshView refreshView = new RefreshView();
ICommand refreshCommand = new Command(() =>
{
    // IsRefreshing is true
    // Refresh data here
    refreshView.IsRefreshing = false;
});
refreshView.Command = refreshCommand;

CollectionView collectionView = new CollectionView();
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");
refreshView.Content = collectionView;
// ...

ユーザーが更新を開始すると、 ICommand プロパティによって Command 定義された が実行され、表示されている項目が更新されます。 更新が行われると、アニメーション化された進行状況円で構成される更新視覚化が表示されます。

iOS および Android CollectionView での CollectionView プル更新の

プロパティの RefreshView.IsRefreshing 値は、 の現在の状態を RefreshView示します。 ユーザーによって更新がトリガーされると、このプロパティは自動的に に true遷移します。 更新が完了したら、 プロパティを にリセットする false必要があります。

の詳細RefreshViewについては、「RefreshView」を参照してくださいXamarin.Forms

データを増分読み込みする

CollectionView では、ユーザーがスクロールするにつれて増分データ仮想化がサポートされます。 これにより、ユーザーがスクロールする際に、Web サービスからデータのページを非同期的に読み込むなどのシナリオが可能になります。 さらに、より多くのデータが読み込まれるポイントは、ユーザーに空白が表示されないか、スクロールを停止するように構成できます。

CollectionView では、データの増分読み込みを制御するために、次のプロパティを定義します。

  • RemainingItemsThresholdintの 、イベントが発生するリストにまだ表示されていない項目の RemainingItemsThresholdReached しきい値。
  • RemainingItemsThresholdReachedCommandに達したときに実行される 型 ICommandRemainingItemsThreshold
  • RemainingItemsThresholdReachedCommandParameter: object 型、RemainingItemsThresholdReachedCommand に渡されるパラメーター。

CollectionViewは、項目が表示されないほどスクロールされたときにCollectionView発生するRemainingItemsThresholdイベントも定義RemainingItemsThresholdReachedします。 このイベントを処理して、より多くの項目を読み込むことができます。 さらに、イベントが RemainingItemsThresholdReached 発生すると、 RemainingItemsThresholdReachedCommand が実行され、ビューモデルで増分データ読み込みが行われます。

プロパティの RemainingItemsThreshold 既定値は -1 です。これは、イベントが RemainingItemsThresholdReached 発生しないかどうかを示します。 プロパティ値が 0 の場合、 の最後の RemainingItemsThresholdReached 項目 ItemsSource が表示されるときにイベントが発生します。 0 より大きい値の RemainingItemsThresholdReached 場合、 にまだスクロールされていない項目の数が含まれている場合 ItemsSource 、イベントが発生します。

注意

CollectionView は、プロパティの RemainingItemsThreshold 値が常に -1 以上になるように プロパティを検証します。

次の XAML の例は、データを CollectionView 増分読み込みする を示しています。

<CollectionView ItemsSource="{Binding Animals}"
                RemainingItemsThreshold="5"
                RemainingItemsThresholdReached="OnCollectionViewRemainingItemsThresholdReached">
    ...
</CollectionView>

これに相当する C# コードを次に示します。

CollectionView collectionView = new CollectionView
{
    RemainingItemsThreshold = 5
};
collectionView.RemainingItemsThresholdReached += OnCollectionViewRemainingItemsThresholdReached;
collectionView.SetBinding(ItemsView.ItemsSourceProperty, "Animals");

このコード例では、 RemainingItemsThresholdReached 5 つの項目がまだスクロールされていない場合にイベントが発生し、応答でイベント ハンドラーが OnCollectionViewRemainingItemsThresholdReached 実行されます。

void OnCollectionViewRemainingItemsThresholdReached(object sender, EventArgs e)
{
    // Retrieve more data here and add it to the CollectionView's ItemsSource collection.
}

注意

データは、 をビューモデルの実装にICommandバインドRemainingItemsThresholdReachedCommandすることで、増分読み込みすることもできます。