定制单元格
其中一个派生自Cell的类名为ViewCell,它定义了一个名为View的属性,允许您为ListView中的项目显示定义自定义可视树。
有几种方法可以定义自定义单元格,但有些方法不如其他方法。也许最大量的工作涉及模仿现有的Cell类,它根本不涉及ViewCell,而是要求您创建特定于平台的单元格渲染器。您也可以得到来自ViewCell类,定义类似于TextCell的绑定属性和其他细胞衍生工具类的几个可绑定属性,并定义可视树在任一XAML或代码的单元格,就像你会为一个做从ContentView派生的自定义视图。然后,您可以像在TextCell中一样在代码或XAML中使用该自定义单元格。
如果要完全在代码中完成工作,可以将DataTemplate构造函数与Func参数一起使用,并在请求每个项目时在代码中构建可视化树。此方法允许您在构建可视树时定义数据绑定,而不是在DataTemplate上设置绑定。
但当然最简单的方法是在ListView元素中的XAML中定义可视树和单元格的绑定。 CustomNamedColorList程序演示了这种技术。一切都在XAML文件中:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:toolkit=
"clr-namespace:Xamarin.FormsBook.Toolkit;assembly=Xamarin.FormsBook.Toolkit"
x:Class="CustomNamedColorList.CustomNamedColorListPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="10, 20, 10, 0"
Android="10, 0"
WinPhone="10, 0" />
</ContentPage.Padding>
<ListView SeparatorVisibility="None"
ItemsSource="{x:Static toolkit:NamedColor.All}">
<ListView.RowHeight>
<OnPlatform x:TypeArguments="x:Int32"
iOS="80"
Android="80"
WinPhone="90" />
</ListView.RowHeight>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView Padding="5">
<Frame OutlineColor="Accent"
Padding="10">
<StackLayout Orientation="Horizontal">
<BoxView x:Name="boxView"
Color="{Binding Color}"
WidthRequest="50"
HeightRequest="50" />
<StackLayout>
<Label Text="{Binding FriendlyName}"
FontSize="22"
VerticalOptions="StartAndExpand" />
<Label Text="{Binding RgbDisplay, StringFormat='RGB = {0}'}"
FontSize="16"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</StackLayout>
</Frame>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage>
在DataTemplate中,property-element标签是ViewCell。 ViewCell的content属性是View,因此您不需要ViewCell.View标记。 相反,ViewCell标记内的可视树隐式设置为View属性。 可视树以ContentView开始,添加一个小填充,然后是一个Frame和一对嵌套的StackLayout元素,带有BoxView和两个Label元素。 当ListView呈现其项目时,每个显示项目的BindingContext是项目本身,因此Binding标记扩展通常非常简单。
请注意,ListView的RowHeight属性设置为依赖于平台的值的属性元素标记。 这些值是通过试验和错误凭经验获得的,并产生以下显示:
在本书中,您已经看到了几个可滚动的颜色列表,例如第4章“滚动堆栈”中的ColorBlocks程序和第8章“代码和XAML协调”中的ColorViewList程序,但我想你会 同意这是解决问题的最优雅方案。
显式设置ListView的RowHeight属性是设置行高的两种方法之一。 您可以通过删除RowHeight设置并将HasUnevenRows属性设置为True来尝试其他方法。 这是CustomNamedColorList程序的变体:
<ListView SeparatorVisibility="None"
ItemsSource="{x:Static toolkit:NamedColor.All}"
HasUnevenRows="True">
<ListView.ItemTemplate>
__
</ListView.ItemTemplate>
</ListView>
HasUnevenRows属性专门用于处理ListView中单元格高度不均匀的情况。 但是,您也可以将它用于所有单元格高度相同但您不确切知道该高度的情况。 使用此设置,将根据可视树计算各行的高度,并使用该高度来分隔行。 在此示例中,单元格的高度由两个Label元素的高度控制。 这些行与从RowHeight属性显式设置的高度略有不同:
尽管HasUnevenRows属性似乎提供了一种比RowHeight更容易调整单元格高度的方法,但它确实会有性能损失,除非您需要,否则应该避免使用它。
但是对于iOS和Android,在定义自定义单元格时必须使用这两个属性中的一个或另一个。 以下是未设置任何属性时发生的情况:
只有Windows平台自动使用可视树的渲染大小来确定行高。
总之,为获得最佳ListView性能,请使用其中一个预定义的Cell类。 如果不能,请使用ViewCell并定义自己的可视树。 尽力使用ViewCell提供特定的RowHeight属性设置。 仅在无法使用时才使用HasUnevenRows。