Xamarin.Forms データの CollectionView

サンプルをダウンロードします。 サンプルをダウンロードする

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

  • ItemsSource型のは、 IEnumerable 表示される項目のコレクションを指定します。の既定値は null です。
  • ItemTemplate型のは、 DataTemplate 表示される項目のコレクション内の各項目に適用するテンプレートを指定します。

これらのプロパティは、オブジェクトによって支えられてい BindableProperty ます。これは、プロパティをデータバインディングのターゲットにできることを意味します。

注意

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

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

CollectionView にデータを設定する

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

重要

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

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

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

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

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

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

注意

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

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

警告

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

項目の外観を定義する

の各項目の外観は、プロパティをに設定すること CollectionView によって定義でき CollectionView.ItemTemplate DataTemplate ます。

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

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

![IOS および Android で各項目がテンプレート化されている CollectionView のスクリーンショット](CollectionView 内のテンプレートアイテムに datatemplate.png データを設定します。

データ テンプレートの詳細については、「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;
    }
}

MonkeyDataTemplateSelectorクラスは、 AmericanMonkey OtherMonkey DataTemplate さまざまなデータテンプレートに設定されるプロパティとプロパティを定義します。 この OnSelectTemplate オーバーライドは、 AmericanMonkey サル名に "America" が含まれている場合に、ジャングルの名前と場所を青緑で表示するテンプレートを返します。 サル名に "America" が含まれていない場合、この上書きによって OnSelectTemplate テンプレートが返されます OtherMonkey 。このテンプレートには、シルバーのサル名と場所が表示されます。

[![IOS および Android での CollectionView runtime item テンプレートの選択のスクリーンショット](CollectionView でのデータイメージ/datatemplateselector.png "ランタイム項目テンプレートの選択"](populate-data-images/datatemplateselector-large.png#lightbox "CollectionView でのランタイム項目テンプレートの選択")

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

重要

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

コンテキスト メニュー

CollectionView では、を使用してデータ項目のコンテキストメニューをサポートしてい SwipeView ます。これにより、スワイプジェスチャを使用してコンテキストメニューが示されます。 SwipeViewは、コンテンツの項目をラップし、そのコンテンツ項目のコンテキストメニュー項目を提供するコンテナーコントロールです。 そのため、 CollectionView SwipeView ラップするコンテンツを定義するを作成し、 SwipeView スワイプジェスチャによって公開されるコンテキストメニュー項目を作成することによって、に対してコンテキストメニューを実装します。 これを実現するには、の SwipeView DataTemplate 各データ項目の外観を定義するのルートビューとしてを設定し 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 ます。また、コントロールが左側からスワイプされると、次の項目が明らかになります。

[IOS および Android での CollectionView コンテキストメニュー項目のスクリーンショット(データの設定-images/swipeview.png "CollectionView with SwipeView context menu items."

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

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

引っ張って更新

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

<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 のプルから更新のスクリーンショット

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

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

データを増分読み込み

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

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

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

CollectionView また、は RemainingItemsThresholdReachedCollectionView 項目が表示されていない大きさまでスクロールしたときに発生するイベントも定義し RemainingItemsThreshold ます。 このイベントを処理して、さらに多くの項目を読み込むことができます。 さらに、 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.
}

注意

をビューモデルの実装にバインドすることによって、データを徐々に読み込むこともでき RemainingItemsThresholdReachedCommand ICommand ます。