Xamarin.Forms CollectionView 數據
CollectionView
包含下列屬性,可定義要顯示的數據及其外觀:
ItemsSource
型IEnumerable
別為 的 ,指定要顯示的專案集合,且預設值為null
。ItemTemplate
類型DataTemplate
為 的 ,指定要套用至要顯示之專案集合中每個專案的範本。
這些屬性是由 BindableProperty
物件所支援,這表示屬性可以是數據系結的目標。
注意
CollectionView
會 ItemsUpdatingScrollMode
定義 屬性,這個屬性表示將新專案加入至其中時的 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
連接的 ViewModel 屬性。
注意
您可以啟用編譯的系結,以改善應用程式中的數據系結效能 Xamarin.Forms 。 如需詳細資訊,請參閱編譯繫結。
如需如何變更版面 CollectionView
配置的資訊,請參閱 Xamarin.Forms CollectionView 版面配置。 如需如何定義 中 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
包含物件和兩Label
個 Image
物件,這些物件都系結至 類別的屬性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 數據範本。
選擇運行時間的項目外觀
您可以藉由將 屬性DataTemplateSelector
設定CollectionView.ItemTemplate
為物件,在執行時間根據專案值,選擇 中CollectionView
每個項目的外觀:
<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
傳回範本,以銀為單位顯示猴子名稱和位置:
如需數據範本選取器的詳細資訊,請參閱 建立 Xamarin.Forms DataTemplateSelector。
重要
使用 CollectionView
時,永遠不要將 物件的根元素 DataTemplate
設定為 ViewCell
。 這會導致擲回例外狀況,因為 CollectionView
沒有單元格的概念。
操作功能表
CollectionView
支援透過 SwipeView
的數據項操作功能表,其會顯示具有撥動手勢的操作功能表。 SwipeView
是包裝內容專案的容器控件,並提供該內容專案的操作功能表項。 因此,藉由建立 SwipeView
,定義包裝的內容SwipeView
,以及撥動手勢所顯示的內容功能表項,即可實CollectionView
作 操作功能表。 這可藉由將 設定 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
內容執行動作,並在控制件從左側撥動時顯示:
SwipeView
支援四個不同的撥動方向,而撥動方向是由物件新增至的方向 SwipeItems
集合 SwipeItems
所定義。 根據預設,撥動專案會在用戶點選時執行。 此外,一旦執行撥動專案,撥動專案就會隱藏並 SwipeView
重新顯示內容。 不過,這些行為可以變更。
如需控件的詳細資訊 SwipeView
,請參閱 Xamarin.Forms SwipeView。
提取以重新整理
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
,請參閱 Xamarin.Forms RefreshView。
以累加方式載入數據
CollectionView
當使用者捲動時,支援累加式數據虛擬化。 這可讓使用者捲動時,以異步方式從 Web 服務載入數據頁面等案例。 此外,可以設定載入更多資料的時間點,讓使用者看不到空白,或停止捲動。
CollectionView
定義下列屬性來控制資料的累加式載入:
RemainingItemsThreshold
類型int
為 的 ,表示清單中尚未顯示RemainingItemsThresholdReached
要引發事件的項目臨界值。RemainingItemsThresholdReachedCommand
,類型ICommand
為 ,會在 到達時RemainingItemsThreshold
執行。RemainingItemsThresholdReachedCommandParameter
,屬於object
類型,這是傳遞至RemainingItemsThresholdReachedCommand
的參數。
CollectionView
也會定義RemainingItemsThresholdReached
在捲動到足以RemainingItemsThreshold
顯示項目時CollectionView
引發的事件。 此事件可以處理以載入更多專案。 此外,在引發事件時 RemainingItemsThresholdReached
, RemainingItemsThresholdReachedCommand
會執行 ,讓累加式數據載入在 viewmodel 中執行。
屬性的 RemainingItemsThreshold
預設值為 -1,表示 RemainingItemsThresholdReached
永遠不會引發事件。 當屬性值為 0 時, RemainingItemsThresholdReached
會在 顯示 中的 ItemsSource
最後一個項目時引發 事件。 對於大於 0 的值,當 包含尚未捲動的項目數目時ItemsSource
,RemainingItemsThresholdReached
就會引發 事件。
注意
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
viewmodel 中的實作,以累加方式載入數據。