自定義 ListView 儲存格外觀
類別 Xamarin.FormsListView
可用來呈現可捲動的清單,這些清單可透過元素的使用 ViewCell
來自定義。 元素 ViewCell
可以顯示文字和影像、指出 true/false 狀態,以及接收用戶輸入。
內建單元格
Xamarin.Forms 隨附適用於許多應用程式的內建資料格:
TextCell
控件用於顯示具有詳細數據文字之選擇性第二行的文字。ImageCell
控件類似於TextCell
s,但包含文字左邊的影像。SwitchCell
控件可用來呈現和擷取開啟/關閉或 true/false 狀態。EntryCell
控制件可用來呈現使用者可以編輯的文字數據。
SwitchCell
和 EntryCell
控件在的內容TableView
中較常用。
TextCell
TextCell
是用來顯示文字的儲存格,選擇性地以第二行做為詳細數據文字。 下列螢幕快照顯示 TextCell
iOS 和 Android 上的專案:
TextCells 會在運行時間轉譯為原生控件,因此相較於自定義 ViewCell
,效能非常好。 TextCells 是可自定義的,可讓您設定下列屬性:
Text
– 第一行顯示的文字,以大字型顯示。Detail
– 以較小的字型顯示於第一行下方的文字。TextColor
– 文字的色彩。DetailColor
– 詳細數據文字的色彩
下列螢幕快照顯示 TextCell
具有自訂色彩屬性的專案:
ImageCell
ImageCell
例如 TextCell
,可用來顯示文字和次要詳細數據文字,而且使用每個平臺的原生控件提供絕佳的效能。 ImageCell
TextCell
不同於 ,它會顯示文字左邊的影像。
下列螢幕快照顯示 ImageCell
iOS 和 Android 上的專案:
ImageCell
當您需要以視覺層面顯示數據清單,例如聯繫人或電影清單時,會很有用。 ImageCell
s 是可自定義的,可讓您設定:
Text
– 以大字型顯示在第一行的文字Detail
– 以較小的字型顯示於第一行下方的文字TextColor
– 文字的色彩DetailColor
– 詳細數據文字的色彩ImageSource
– 要顯示在文字旁的影像
下列螢幕快照顯示 ImageCell
具有自訂色彩屬性的專案:
自定義儲存格
自定義儲存格可讓您建立內建單元格不支援的儲存格配置。 例如,您可能想要呈現具有兩個具有相等權數卷標的單元格。 TextCell
會不足,TextCell
因為 有一個較小的標籤。 大部分的數據格自定義都會新增其他唯讀數據(例如其他標籤、影像或其他顯示資訊)。
所有自定義儲存格都必須衍生自 ViewCell
,這是所有內建單元格類型所使用的相同基類。
Xamarin.Forms提供控件的ListView
快取行為,可改善某些自定義單元格類型的捲動效能。
下列螢幕快照顯示自訂儲存格的範例:
XAML
您可以使用下列 XAML 來建立上一個螢幕快照中顯示的自訂儲存格:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="demoListView.ImageCellPage">
<ContentPage.Content>
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="#eee"
Orientation="Vertical">
<StackLayout Orientation="Horizontal">
<Image Source="{Binding image}" />
<Label Text="{Binding title}"
TextColor="#f35e20" />
<Label Text="{Binding subtitle}"
HorizontalOptions="EndAndExpand"
TextColor="#503026" />
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
XAML 的運作方式如下:
- 自定義儲存格巢狀於
DataTemplate
內,位於內ListView.ItemTemplate
。 這與使用任何內建單元格的程式相同。 ViewCell
是自定義儲存格的類型。 專案的子系DataTemplate
必須是 或衍生自 類別ViewCell
。- 在 內
ViewCell
,配置可由任何 Xamarin.Forms 版面配置管理。 在此範例中,配置是由 管理StackLayout
,可自定義背景色彩。
注意
任何可系結的屬性 StackLayout
都可以系結在自定義單元格內。 不過,XAML 範例中不會顯示這項功能。
代碼
您也可以在程式代碼中建立自定義儲存格。 首先,必須建立衍生自 ViewCell
的自定義類別:
public class CustomCell : ViewCell
{
public CustomCell()
{
//instantiate each of our views
var image = new Image ();
StackLayout cellWrapper = new StackLayout ();
StackLayout horizontalLayout = new StackLayout ();
Label left = new Label ();
Label right = new Label ();
//set bindings
left.SetBinding (Label.TextProperty, "title");
right.SetBinding (Label.TextProperty, "subtitle");
image.SetBinding (Image.SourceProperty, "image");
//Set properties for desired design
cellWrapper.BackgroundColor = Color.FromHex ("#eee");
horizontalLayout.Orientation = StackOrientation.Horizontal;
right.HorizontalOptions = LayoutOptions.EndAndExpand;
left.TextColor = Color.FromHex ("#f35e20");
right.TextColor = Color.FromHex ("503026");
//add views to the view hierarchy
horizontalLayout.Children.Add (image);
horizontalLayout.Children.Add (left);
horizontalLayout.Children.Add (right);
cellWrapper.Children.Add (horizontalLayout);
View = cellWrapper;
}
}
在頁面建構函式中,ListView 的 ItemTemplate
屬性會設定為 DataTemplate
具有指定型別的 CustomCell
:
public partial class ImageCellPage : ContentPage
{
public ImageCellPage ()
{
InitializeComponent ();
listView.ItemTemplate = new DataTemplate (typeof(CustomCell));
}
}
系結內容變更
系結至自定義數據格類型的 BindableProperty
實例時,顯示 BindableProperty
值的 UI 控件應該使用 OnBindingContextChanged
覆寫來設定要在每個單元格中顯示的數據,而不是單元格建構函式,如下列程式代碼範例所示:
public class CustomCell : ViewCell
{
Label nameLabel, ageLabel, locationLabel;
public static readonly BindableProperty NameProperty =
BindableProperty.Create ("Name", typeof(string), typeof(CustomCell), "Name");
public static readonly BindableProperty AgeProperty =
BindableProperty.Create ("Age", typeof(int), typeof(CustomCell), 0);
public static readonly BindableProperty LocationProperty =
BindableProperty.Create ("Location", typeof(string), typeof(CustomCell), "Location");
public string Name
{
get { return(string)GetValue (NameProperty); }
set { SetValue (NameProperty, value); }
}
public int Age
{
get { return(int)GetValue (AgeProperty); }
set { SetValue (AgeProperty, value); }
}
public string Location
{
get { return(string)GetValue (LocationProperty); }
set { SetValue (LocationProperty, value); }
}
...
protected override void OnBindingContextChanged ()
{
base.OnBindingContextChanged ();
if (BindingContext != null)
{
nameLabel.Text = Name;
ageLabel.Text = Age.ToString ();
locationLabel.Text = Location;
}
}
}
事件 OnBindingContextChanged
引發時 BindingContextChanged
,將會呼叫 覆寫,以響應屬性變更的值 BindingContext
。 因此,當變更時 BindingContext
,顯示 BindableProperty
值的UI控制項應該設定其數據。 請注意, BindingContext
應該檢查 是否有 null
值,因為您可以針對垃圾收集設定 Xamarin.Forms 這個值,這反過來又會導致 OnBindingContextChanged
呼叫覆寫。
或者,UI 控制件可以系結至 BindableProperty
實例以顯示其值,而不需要覆寫 OnBindingContextChanged
方法。
注意
覆寫 OnBindingContextChanged
時,請確定呼叫基類的 方法,讓已註冊的 OnBindingContextChanged
委派接收 BindingContextChanged
事件。
在 XAML 中,可以將自訂儲存格型態系結至數據,如下列程式代碼範例所示:
<ListView x:Name="listView">
<ListView.ItemTemplate>
<DataTemplate>
<local:CustomCell Name="{Binding Name}" Age="{Binding Age}" Location="{Binding Location}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
這會將 Name
實例中的 CustomCell
、 Age
和 Location
可系結屬性系結至Name
基礎集合中每個物件的、 Age
和 Location
屬性。
C# 中的對等系結會顯示在下列程式代碼範例中:
var customCell = new DataTemplate (typeof(CustomCell));
customCell.SetBinding (CustomCell.NameProperty, "Name");
customCell.SetBinding (CustomCell.AgeProperty, "Age");
customCell.SetBinding (CustomCell.LocationProperty, "Location");
var listView = new ListView
{
ItemsSource = people,
ItemTemplate = customCell
};
在 iOS 和 Android 上,如果 ListView
正在回收元素,而自定義儲存格使用自定義轉譯器,則自定義轉譯器必須正確實作屬性變更通知。 當儲存格重複使用時,當系結內容更新為可用儲存格時,其屬性值將會變更,並 PropertyChanged
引發事件。 如需詳細資訊,請參閱 自定義 ViewCell。 如需儲存格回收的詳細資訊,請參閱 快取策略。