Xamarin.Forms CollectionView データ

Download Sample サンプルをダウンロードします

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

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

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

注意

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

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

CollectionView にデータを設定する

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

警告

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

項目の外観を定義する

内の各項目の外観は、プロパティDataTemplateCollectionView次のように設定CollectionView.ItemTemplateすることで定義できます。

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

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

Screenshot of CollectionView where each item is templated, on iOS and Android

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

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

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

<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 返します。このテンプレートには、サルの名前と場所が銀色で表示されます。

Screenshot of CollectionView runtime item template selection, on iOS and Android

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

重要

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

コンテキスト メニュー

CollectionView は、スワイプ ジェスチャを使用してコンテキスト メニューを SwipeView表示する、データ項目のコンテキスト メニューをサポートします。 これは SwipeView 、コンテンツの項目をラップし、そのコンテンツの項目のコンテキスト メニュー項目を提供するコンテナー コントロールです。 したがって、コンテキスト メニューは、ラップするコンテンツを定義するSwipeViewコンテキスト SwipeView メニューと、スワイプ ジェスチャによって表示されるコンテキスト メニュー項目を作成することによって、a 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 内の各項目の外観を定義する CollectionViewa です。 スワイプ項目は、コンテンツに対してアクションを SwipeView 実行するために使用され、コントロールが左側からスワイプされると表示されます。

Screenshot of CollectionView context menu items, on iOS and Android

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

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

引っ張って更新

CollectionView では、プルを使用して更新機能を RefreshViewサポートしています。これにより、項目の一覧をプルダウンして、表示されるデータを更新できます。 これは RefreshView 、子がスクロール可能なコンテンツをサポートしている場合に、その子に更新機能をプルして提供するコンテナー コントロールです。 したがって、更新するプルは、次の子として設定することで、RefreshViewa 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 定義されたプロパティが実行され、表示されている項目が更新されます。 更新の実行中に更新の視覚エフェクトが表示されます。これは、アニメーション化された進行状況の円で構成されます。

Screenshot of CollectionView pull-to-refresh, on iOS and Android

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

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

データを段階的に読み込む

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

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

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

CollectionView また、 RemainingItemsThresholdReached 項目が表示されていないほどスクロールされたときに CollectionView 発生する 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 段階的に読み込むこともできます。