Xamarin.Forms CollectionView データ
CollectionView
には、表示するデータとその外観を定義する次のプロパティが含まれています。
ItemsSource
型IEnumerable
の は、表示する項目のコレクションを指定し、既定値はnull
です。ItemTemplate
型DataTemplate
の は、表示する項目のコレクション内の各項目に適用するテンプレートを指定します。
これらのプロパティはオブジェクトによって 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.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; }
}
次のスクリーンショットは、リスト内の各項目をテンプレート化した結果を示しています。
データ テンプレートの詳細については、「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" が含まれている場合に、サルの名前と場所が teal に表示されます。 サルの名前に "America" が含まれていない場合、 OnSelectTemplate
オーバーライドはテンプレートを OtherMonkey
返します。これにより、サルの名前と場所が銀色で表示されます。
データ テンプレート セレクターの詳細については、「 DataTemplateSelector の Xamarin.Forms 作成」を参照してください。
重要
を使用 CollectionView
する場合は、オブジェクトのルート要素を DataTemplate
に ViewCell
設定しないでください。 これにより、セルの概念がないため CollectionView
、例外がスローされます。
コンテキスト メニュー
CollectionView
では、 を介した SwipeView
データ項目のコンテキスト メニューがサポートされています。これにより、スワイプ ジェスチャを使用してコンテキスト メニューが表示されます。 SwipeView
は、コンテンツの項目をラップし、そのコンテンツ項目のコンテキスト メニュー項目を提供するコンテナー コントロールです。 したがって、 のコンテキスト メニューは、ラップするコンテンツSwipeView
をSwipeView
定義する を作成し、スワイプ ジェスチャによって表示されるコンテキスト メニュー項目を作成することによって実装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
実行するために使用され、コントロールが左側からスワイプされると表示されます。
SwipeView
は 4 つの異なるスワイプ方向をサポートし、オブジェクトが追加される方向コレクションによってスワイプ方向 SwipeItems
が SwipeItems
定義されます。 既定では、スワイプ項目はユーザーによってタップされたときに実行されます。 さらに、スワイプ項目が実行されると、スワイプ項目は非表示になり、 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
定義された が実行され、表示されている項目が更新されます。 更新が行われると、アニメーション化された進行状況円で構成される更新視覚化が表示されます。
プロパティの RefreshView.IsRefreshing
値は、 の現在の状態を RefreshView
示します。 ユーザーによって更新がトリガーされると、このプロパティは自動的に に true
遷移します。 更新が完了したら、 プロパティを にリセットする false
必要があります。
の詳細RefreshView
については、「RefreshView」を参照してくださいXamarin.Forms。
データを増分読み込みする
CollectionView
では、ユーザーがスクロールするにつれて増分データ仮想化がサポートされます。 これにより、ユーザーがスクロールする際に、Web サービスからデータのページを非同期的に読み込むなどのシナリオが可能になります。 さらに、より多くのデータが読み込まれるポイントは、ユーザーに空白が表示されないか、スクロールを停止するように構成できます。
CollectionView
では、データの増分読み込みを制御するために、次のプロパティを定義します。
RemainingItemsThreshold
型int
の 、イベントが発生するリストにまだ表示されていない項目のRemainingItemsThresholdReached
しきい値。RemainingItemsThresholdReachedCommand
に達したときに実行される 型ICommand
のRemainingItemsThreshold
。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
することで、増分読み込みすることもできます。