通过


基本绑定

浏览示例

.NET Multi-platform App UI (.NET MAUI) 数据绑定在两个对象之间链接一对属性,其中至少一个对象通常是用户界面对象。 这两个对象称为“目标”和“源”:

  • “目标”是用来设置数据绑定的对象(以及属性)。
  • 源是数据绑定引用的对象(和属性)。

在最简单的情况下,数据从源流到目标,这意味着目标属性值是从源属性的值设置的。 但是,在某些情况下,数据也可以从目标流向源,或者双向流动。

重要

目标始终是在其上设置数据绑定的对象,即使它提供数据而不接收数据也是如此。

带有绑定上下文的绑定

请考虑以下 XAML 示例,其目的是通过操作 Slider 来旋转 Label:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicCodeBindingPage"
             Title="Basic Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="48"
               HorizontalOptions="Center"
               VerticalOptions="Center" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

在没有数据绑定的情况下,你可以为 SliderValueChanged 事件设置一个事件处理程序,该处理程序访问 SliderValue 属性,并将该值设置为 LabelRotation 属性。 数据绑定会自动执行此任务,因此不再需要事件处理程序及其中的代码。

可以在派生自 BindableObject 的任何类的实例上设置绑定,这些类包括 Element、VisualElement、View 和其他派生项。 绑定始终在目标对象上进行设置。 绑定引用源对象。 要设置数据绑定,请使用目标类的以下两个成员:

  • BindingContext 属性指定源对象。
  • SetBinding 方法指定目标属性和源属性。

在本例中,Label 是绑定目标,Slider 是绑定源。 更改 Slider 源会影响 Label 目标的旋转。 数据从源流向目标。

在代码中编写的绑定有时使用字符串路径,这些路径在运行时通过反射进行解析。 但是,SetBinding 扩展方法也提供了一个重载,该重载使用 Func 参数来定义绑定:

public partial class BasicCodeBindingPage : ContentPage
{
    public BasicCodeBindingPage()
    {
        InitializeComponent();

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, static (Slider slider) => slider.Value);
    }
}

Label 对象是绑定目标,因此它是设置此属性和调用该方法的对象。 参数 Func 指示绑定源,即 Slider. SetBinding 方法在绑定目标上被调用,但需同时指定目标属性和源属性。 目标属性被指定为一个 BindableProperty 对象:Label.RotationProperty。 源属性是使用 lambda 表达式指定的,并表示 SliderValue 属性。

重要

目标属性必须由可绑定属性支持。 因此,目标对象必须是从 BindableObject 派生的类的一个实例。 有关详细信息,请参阅可绑定属性

在上面的示例中,绑定源是使用 a Func指定的,这可确保为提高运行时性能编译绑定表达式。 有关已编译绑定的详细信息,请参阅 已编译绑定

通过操控 SliderLabel 会相应地旋转。

基本代码绑定。

或者,可以在 XAML 中指定数据绑定:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BasicXamlBindingPage"
             Title="Basic XAML Binding">
    <StackLayout Padding="10, 0">
        <Label x:DataType="Slider"
               Text="TEXT"
               FontSize="80"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               BindingContext="{x:Reference Name=slider}"
               Rotation="{Binding Path=Value}" />

        <Slider x:Name="slider"
                Maximum="360"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

正如在代码中一样,数据绑定是在目标对象Label上设置的。 有两个 XAML 标记扩展可用于定义数据绑定:

  • x:Reference 标记扩展是必需的,用于引用源对象,即命名为 sliderSlider
  • Binding 标记扩展将 LabelRotation 属性链接到 SliderValue 属性。

有关 XAML 标记扩展的更多信息,请参阅使用 XAML 标记扩展。

此外,位于Label上的x:DataType属性指示XAML编译器编译Label上的绑定表达式以提升运行时性能,并指定该绑定表达式应针对Slider类型进行解析。 有关详细信息,请参阅已编译绑定。

注意

源属性由 Path 标记扩展的 Binding 属性指定,它对应于 Path 类的 Binding 属性。

XAML 标记扩展(如 x:ReferenceBinding)可以定义“内容属性”,对于 XAML 标记扩展,这意味着属性名称不需要出现。 Name 属性是 x:Reference 的内容属性,Path 属性是 Binding 的内容属性,这意味着可以从表达式中省略它们:

<Label x:DataType="Slider"
       Text="TEXT"
       FontSize="80"
       HorizontalOptions="Center"
       VerticalOptions="Center"
       BindingContext="{x:Reference slider}"
       Rotation="{Binding Value}" />

不使用绑定上下文的绑定

BindingContext 属性是数据绑定的重要组件,但并不总是必要的。 可以改为在 SetBinding 调用或 Binding 标记扩展中指定源对象:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeCodeBindingPage"
             Title="Alternative Code Binding">
    <StackLayout Padding="10, 0">
        <Label x:Name="label"
               Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="Center" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

在此示例中,Slider 被定义以控制 LabelScale 属性。 因此,将滑块的范围设置为-2到2。

代码隐藏文件使用 SetBinding 方法来设置绑定,第二个参数 Func 用于获取 Slider 的值。

public partial class AlternativeCodeBindingPage : ContentPage
{
    public AlternativeCodeBindingPage()
    {
        InitializeComponent();

        label.SetBinding(Label.ScaleProperty, static (Slider s) => s.Value, source: slider);
    }
}

注意

VisualElement类还定义了ScaleXScaleY属性,这些属性可以在水平和垂直方向上以不同方式缩放VisualElement

或者,可以在 XAML 中指定数据绑定:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.AlternativeXamlBindingPage"
             Title="Alternative XAML Binding">
    <StackLayout Padding="10, 0">
        <Label Text="TEXT"
               FontSize="40"
               HorizontalOptions="Center"
               VerticalOptions="Center"
               Scale="{Binding x:DataType='Slider',
                               Source={x:Reference slider},
                               Path=Value}" />

        <Slider x:Name="slider"
                Minimum="-2"
                Maximum="2"
                VerticalOptions="Center" />
    </StackLayout>
</ContentPage>

在此示例中,Binding 标记扩展设置了两个属性,SourcePath,用逗号分隔。 Source 属性设置为嵌入的 x:Reference 标记扩展,其语法与设置 BindingContext 相同。

一个标记扩展的 Binding 的内容属性是 Path,但是只有当 Path= 是表达式中的第一个属性时,标记扩展的这个部分才能被去除。 若要消除 Path= 部分,需要交换这两个属性:

Scale="{Binding Value, Source={x:Reference slider}, x:DataType='Slider'}" />

尽管 XAML 标记扩展通常由大括号分隔,但它们也可以表示为对象元素:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding x:DataType="Slider"
                 Source="{x:Reference slider}"
                 Path="Value" />
    </Label.Scale>
</Label>

在此示例中,SourcePath 属性是常规 XAML 属性。 值出现在引号中,属性之间没有逗号分隔。 x:Reference标记扩展也可以成为对象元素:

<Label Text="TEXT"
       FontSize="40"
       HorizontalOptions="Center"
       VerticalOptions="Center">
    <Label.Scale>
        <Binding x:DataType="Slider"
                 Path="Value">
            <Binding.Source>
                <x:Reference Name="slider" />
            </Binding.Source>
        </Binding>
    </Label.Scale>
</Label>

这种语法并不常见,但当涉及到复杂对象时,有时它也是必要的。

到目前为止显示的示例将 BindingContext 属性和 Source 属性设置为 x:Reference 标记扩展,用于引用页面上的其他视图。 这两个属性的类型是 Object,可以将它们设置为包含适合作为数据源绑定的属性的任何对象。 还可以将 BindingContextSource 属性设置为 x:Static 标记扩展,以引用静态属性或字段的值,或将 StaticResource 标记扩展用于引用存储在资源字典中的对象,或者直接设置为对象,而这对象通常是视图模型的实例。

注意

还可以将 BindingContext 属性设置为 Binding 对象,以便 BindingSourcePath 属性定义绑定上下文。

绑定上下文继承

可以使用 BindingContext 属性或 Source 属性来指定 Binding 对象的源对象。 如果两者都已设置,则 Source 属性优先于 BindingContext

重要

BindingContext 属性值是通过视觉树继承的。

以下 XAML 示例演示了绑定上下文继承:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="DataBindingDemos.BindingContextInheritancePage"
             Title="BindingContext Inheritance">
    <StackLayout Padding="10">
        <StackLayout x:DataType="Slider"
                     VerticalOptions="Fill"
                     BindingContext="{x:Reference slider}">

            <Label Text="TEXT"
                   FontSize="80"
                   HorizontalOptions="Center"
                   VerticalOptions="End"
                   Rotation="{Binding Value}" />

            <BoxView Color="#800000FF"
                     WidthRequest="180"
                     HeightRequest="40"
                     HorizontalOptions="Center"
                     VerticalOptions="Start"
                     Rotation="{Binding Value}" />
        </StackLayout>

        <Slider x:Name="slider"
                Maximum="360" />
    </StackLayout>
</ContentPage>

在此示例中,BindingContextStackLayout 属性被设置为 slider 对象。 此绑定上下文被Label和BoxView继承,并且它们的Rotation属性都设置为Slider的Value属性:

Binding context inheritance.绑定上下文继承。