数据绑定所选项目
使用所选项的一种方法涉及在代码隐藏文件中处理ListView的ItemSelected事件,并使用SelectedItem属性获取新选择的项。 (本章稍后将举例说明。)但在许多情况下,您需要使用与SelectedItem属性的数据绑定。 ListViewArray程序使用BoxView的Color属性定义ListView的SelectedItem属性之间的数据绑定:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ListViewArray.ListViewArrayPage">
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness"
iOS="10, 20, 10, 0"
Android="10, 0"
WinPhone="10, 0" />
</ContentPage.Padding>
<StackLayout>
<ListView x:Name="listView"
SelectedItem="{Binding Source={x:Reference boxView},
Path=Color,
Mode=TwoWay}">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
<x:Static Member="Color.Aqua" />
<x:Static Member="Color.Black" />
<x:Static Member="Color.Blue" />
<x:Static Member="Color.Fuchsia" />
<x:Static Member="Color.Gray" />
<x:Static Member="Color.Green" />
<x:Static Member="Color.Lime" />
<x:Static Member="Color.Maroon" />
<Color>Navy</Color>
<Color>Olive</Color>
<Color>Pink</Color>
<Color>Purple</Color>
<Color>Red</Color>
<Color>Silver</Color>
<Color>Teal</Color>
<Color>White</Color>
<Color>Yellow</Color>
</x:Array>
</ListView.ItemsSource>
</ListView>
<BoxView x:Name="boxView"
Color="Lime"
HeightRequest="100" />
</StackLayout>
</ContentPage>
此XAML文件直接从项数组中设置ListView的ItemsSource属性。 ItemsSource不是ListView的内容属性(实际上,ListView根本没有内容属性),因此您需要显式的ListView.ItemsSource标记。 x:Array元素需要Type属性,指示数组中项目的类型。为了多样化,显示了两种指定颜色值的不同方法。您可以使用任何导致Color类型值的内容。
ListView的ItemsSource属性始终填充对象而不是可视元素。例如,如果要在ListView中显示字符串,请使用代码中的字符串对象或XAML文件中的x:String元素。不要使用Label元素填充ItemsSource集合!
ListView是可滚动的,通常当可滚动视图是StackLayout的子视图时,需要FillAndExpand的VerticalOptions设置。但是,ListView本身将其HorizontalOptions和VerticalOptions属性设置为FillAndExpand。
数据绑定从BoxView的Color属性定向ListView的SelectedItem属性。您可能更倾向于反转该绑定的源和目标属性,如下所示:
<BoxView x:Name="boxView"
Color="{Binding Source={x:Reference listView},
Path=SelectedItem}"
HeightRequest="100" />
但是,默认情况下,ListView的SelectedItem属性为null,表示未选择任何内容,并且绑定将失败并显示NullReferenceException。 要在BoxView上进行绑定,您需要在添加项目后初始化ListView的SelectedItem属性:
<ListView x:Name="listView">
<ListView.ItemsSource>
<x:Array Type="{x:Type Color}">
__
</x:Array>
</ListView.ItemsSource>
<ListView.SelectedItem>
<Color>Lime</Color>
</ListView.SelectedItem>
</ListView>
一个更好的方法 - 您将与MVVM一起使用的方法 - 是在ListView的SelectedItem属性上设置绑定。 SelectedItem的默认绑定模式是OneWayToSource,这意味着以下绑定将BoxView的颜色设置为ListView中选择的任何项目:
<ListView x:Name="listView"
SelectedItem="{Binding Source={x:Reference boxView},
Path=Color}">
__
</ListView>
但是,如果您还想从绑定源初始化SelectedItem属性,请使用ListViewArray程序中的XAML文件中所示的TwoWay绑定:
<StackLayout>
<ListView x:Name="listView"
SelectedItem="{Binding Source={x:Reference boxView},
Path=Color,
Mode=TwoWay}">
__
</ListView>
<BoxView x:Name="boxView"
Color="Lime"
HeightRequest="100" />
</StackLayout>
您将看到程序启动时选择ListView中的“Lime”条目:
实际上,如果不检查RGB值,很难判断这是否真的是“Lime”条目。尽管Color结构定义了一组带有颜色名称的静态字段,但Color值本身无法通过名称进行标识。当数据绑定将Lime颜色值设置为ListView的SelectedItem属性时,ListView可能使用Color结构的Equals方法在其内容中找到匹配项,该方法比较两种颜色的组件。
ListView显示的改进当然是一个高优先级!
如果仔细检查ListViewArray屏幕,您会发现Color项目的显示顺序与它们在数组中的定义顺序不同。 ListViewArray程序还有另一个目的:演示ListView不会将集合的副本设置为其ItemsSource属性。相反,它直接将该集合对象用作项目的源。在里面
代码隐藏文件,在InitializeComponent调用返回后,ListViewArrayPage的构造函数执行就地数组排序以按顺序对项目进行排序:
public partial class ListViewArrayPage : ContentPage
{
public ListViewArrayPage()
{
InitializeComponent();
Array.Sort<Color>((Color[])listView.ItemsSource,
(Color color1, Color color2) =>
{
if (color1.Hue == color2.Hue)
return Math.Sign(color1.Luminosity - color2.Luminosity);
return Math.Sign(color1.Hue - color2.Hue);
});
}
}
这种排序发生在ItemsSource属性设置之后,当InitializeComponent调用解析XAML时,但在ListView实际在布局过程中显示其内容之前。
此代码表示您可以动态更改ListView使用的集合。 但是,如果希望ListView在集合更改时更改其显示,则必须以某种方式通知ListView其ItemsSource属性引用的集合中发生了更改。
让我们更详细地研究一下这个问题。