Code和XAML
虽然大多数数据绑定都是在XAML中定义的,但您应该知道如何在代码中执行一个。 这是在代码中设置数据绑定的一种方式(但不是唯一的方法):
- 在目标对象上设置BindingContext属性以引用源对象。
- 在目标对象上调用SetBinding以指定目标和源属性。
BindingContext属性由BindableObject定义。 (它是BindableObject定义的唯一属性。)SetBinding方法也由BindableObject定义,但BindableObjectExtensions类中的SetBinding方法还有两个额外的重载。 target属性被指定为BindableProperty; source属性通常指定为字符串。
OpacityBindingCode程序创建两个元素,Label和Slider,并定义一个数据绑定,该绑定以Slider的Value属性为目标的Label的Opacity属性:
public class OpacityBindingCodePage : ContentPage
{
public OpacityBindingCodePage()
{
Label label = new Label
{
Text = "Opacity Binding Demo",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.Center
};
Slider slider = new Slider
{
VerticalOptions = LayoutOptions.CenterAndExpand
};
// Set the binding context: target is Label; source is Slider.
label.BindingContext = slider;
// Bind the properties: target is Opacity; source is Value.
label.SetBinding(Label.OpacityProperty, "Value");
// Construct the page.
Padding = new Thickness(10, 0);
Content = new StackLayout
{
Children = { label, slider }
};
}
}
这是连接两个对象的属性设置:
label.BindingContext = slider;
标签对象是目标,滑块对象是源。这是链接两个属性的方法调用:
label.SetBinding(Label.OpacityProperty, "Value");
SetBinding的第一个参数是BindableProperty类型,这是target属性的要求。 但source属性仅指定为字符串。 它可以是任何类型的财产。
屏幕截图演示了您不需要设置事件处理程序来使用Slider来控制页面上的其他元素:
当然,有人正在设置一个事件处理程序。 在封面下,当绑定初始化自身时,它还通过从Slider的Value属性设置Label的Opacity属性来对目标执行初始化。 (正如您在上一章中发现的那样,当您自己设置事件处理程序时,此初始化不会自动发生。)然后内部绑定代码检查源对象(在本例中为Slider)是否实现了INotifyPropertyChanged接口。 如果是这样,则在Slider上设置PropertyChanged处理程序。 每当Value属性更改时,绑定都会将新值设置为Label的Opacity属性。
在XAML中重现绑定涉及两个您尚未看到的标记扩展:
- x:Reference,是XAML 2009规范的一部分。
- Binding,它是Microsoft基于XAML的用户界面的一部分。
x:Reference绑定扩展非常简单,但Binding标记扩展是所有Xamarin.Forms中最广泛和最复杂的标记扩展。 它将在本章的过程中逐步介绍。
以下是在XAML中设置数据绑定的方法:
- 将目标元素(Label)的BindingContext属性设置为引用源元素(Slider)的x:Reference标记扩展。
- 将target属性(Label的Opacity属性)设置为引用source属性的Binding标记扩展(Slider的Value属性)。
OpacityBindingXaml项目显示完整的标记:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="OpacityBindingXaml.OpacityBindingXamlPage"
Padding="10, 0">
<StackLayout>
<Label Text="Opacity Binding Demo"
FontSize="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
BindingContext="{x:Reference Name=slider}"
Opacity="{Binding Path=Value}" />
<Slider x:Name="slider"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>
绑定的两个标记扩展是Label中的最后两个属性设置。 除了对InitializeComponent的标准调用之外,代码隐藏文件不包含任何内容。
在标记中设置BindingContext时,很容易忘记x:Reference标记扩展并简单地指定源名称,但这不起作用。
Binding标记表达式的Path参数指定source属性。 为什么这个论点叫做Path而不是Property? 你会在本章后面看到原因。
您可以将标记缩短一点。 为Reference提供支持的公共类是ReferenceExtension,它将其content属性定义为Name。 BindingExtension(不是公共类)的content属性是Path,因此您不需要Name和Path参数以及等号:
<Label Text="Opacity Binding Demo"
FontSize="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
BindingContext="{x:Reference slider}"
Opacity="{Binding Value}" />
或者,如果您想使标记更长,可以将BindingContext和Opacity属性作为属性元素分解,并使用x的常规元素语法设置它们:引用和绑定:
<Label Text="Opacity Binding Demo"
FontSize="Large"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center">
<Label.BindingContext>
<x:Reference Name="slider" />
</Label.BindingContext>
<Label.Opacity>
<Binding Path="Value" />
</Label.Opacity>
</Label>
正如您将看到的,对于绑定,使用属性元素有时与数据绑定相关。