Enlaces básicos

Browse sample. Examinar la muestra.

Un enlace de datos de .NET Multi-platform App UI (.NET MAUI) enlaza un par de propiedades entre dos objetos, del que al menos uno suele ser un objeto de interfaz de usuario. Estos dos objetos se denominan el destino y el origen:

  • El destino es el objeto (y la propiedad) en la que se establece el enlace de datos.
  • El origen es el objeto (y la propiedad) al que hace referencia el enlace de datos.

en el caso más simple, los datos fluyen desde el origen al destino, lo que significa que el valor de la propiedad de destino se establece en el valor de la propiedad de origen. Pero en algunos casos, los datos también pueden fluir desde el destino al origen, o en ambas direcciones.

Importante

El destino siempre es el objeto en el que se establece el enlace de datos, incluso si ofrece datos en lugar de recibirlos.

Enlaces con un contexto de enlace

Considera el ejemplo XAML siguiente, cuya intención es girar Label mediante la manipulación de Slider:

<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>

Sin los enlaces de datos, se establecería el evento ValueChanged del elemento Slider en un controlador de eventos que accede a la propiedad Value del elemento Slider y establece ese valor en la propiedad Rotation del elemento Label. El enlace de datos automatiza esta tarea; el controlador de eventos y el código que contiene ya no son necesarios.

Puede establecer un enlace en una instancia de cualquier clase que se derive de BindableObject, lo que incluye las derivadas Element, VisualElement, View y View. El enlace siempre se establece en el objeto de destino. El enlace hace referencia al objeto de origen. Para establecer el enlace de datos, use los dos miembros siguientes de la clase de destino:

  • La propiedad BindingContext especifica el objeto de origen.
  • El método SetBinding especifica la propiedad de destino y la de origen.

En este ejemplo, Label es el destino de enlace y Slider es el origen de enlace. Los cambios en el origen de Slider afectan a la rotación del destino de Label. Los datos fluyen del origen al destino.

El método SetBinding definido por BindableObject tiene un argumento de tipo BindingBase del que se deriva la clase Binding, pero existen otros métodos SetBinding definidos por la clase BindableObjectExtensions. El código subyacente para XAML usa un método de extensión SetBinding más sencillo de la clase BindableObjectExtensions:

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

        label.BindingContext = slider;
        label.SetBinding(Label.RotationProperty, "Value");
    }
}

El objeto Label es el destino de enlace, por lo que es el objeto en el que se establece esta propiedad y en el que se llama al método. La propiedad BindingContext indica el origen de enlace, que es el elemento Slider. El método SetBinding se llama en el destino de enlace, pero especifica tanto la propiedad de destino como la de origen. La propiedad de destino se especifica como un objeto BindableProperty: Label.RotationProperty. La propiedad de origen se especifica como una cadena e indica la propiedad Value de Slider.

Importante

La propiedad de destino debe estar respaldada por una propiedad enlazable. Por lo tanto, el objeto de destino debe ser una instancia de una clase que se derive de BindableObject. Para obtener más información, consulta Propiedades enlazables.

La propiedad de origen se especifica como una cadena. De forma interna, se usa la reflexión para acceder a la propiedad real. Pero en este caso concreto, la propiedad Value también está respaldada por una propiedad enlazable.

Al manipular el elemento Slider, el elemento Label gira según corresponda:

Basic code binding.

Como alternativa, el enlace de datos se puede especificar en 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 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>

Al igual que en el código, el enlace de datos se establece en el objeto de destino, que es el elemento Label. Se usan dos extensiones de marcado XAML para definir el enlace de datos:

  • La extensión de marcado x:Reference es necesaria para hacer referencia al objeto de origen, que es el elemento Slider denominado slider.
  • La extensión de marcado Binding enlaza la propiedad Rotation de Label a la propiedad Value de Slider.

Para obtener más información sobre las extensiones de marcado XAML, consulta Consumo de extensiones de marcado XAML.

Nota:

La propiedad de origen se especifica con la propiedad Path de la extensión de marcado Binding, que se corresponde con la propiedad Path de la clase Binding.

en las extensiones de marcado XAML como x:Reference y Binding se pueden definir atributos de propiedad de contenido, lo que para las extensiones de marcado XAML significa que no es necesario que aparezca el nombre de propiedad. La propiedad Name es la propiedad de contenido de x:Reference y la propiedad Path es la propiedad de contenido de Binding, lo que significa que se pueden eliminar de las expresiones:

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

Enlaces sin un contexto de enlace

La propiedad BindingContext es un componente importante de los enlaces de datos, pero no siempre es necesaria. El objeto de origen se puede especificar en la llamada a SetBinding o en la extensión de marcado 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="CenterAndExpand" />

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

En este ejemplo, Slider está definido para controlar la propiedad Scale de Label. Por ese motivo, Slider se establece para un intervalo de -2 a 2:

El archivo de código subyacente establece el enlace con el método SetBinding, con el segundo argumento siendo un constructor para la clase Binding:

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

        label.SetBinding(Label.ScaleProperty, new Binding("Value", source: slider));
    }
}

El constructor Binding tiene seis parámetros, por lo que el parámetro source se especifica con un argumento con nombre. El argumento es el objeto slider.

Nota:

La clase VisualElement también define las propiedades ScaleX y ScaleY, que pueden escalar el elemento VisualElement de forma diferente en dirección horizontal y vertical.

Como alternativa, el enlace de datos se puede especificar en 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 Source={x:Reference slider},
                               Path=Value}" />

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

En este ejemplo, la extensión de marcado Binding tiene dos propiedades establecidas, Source y Path, separadas por una coma. La propiedad Source se establece en una extensión de marcado x:Reference insertada que, en caso contrario, tiene la misma sintaxis que la configuración de BindingContext.

La propiedad de contenido de la extensión de marcado Binding es Path, pero la parte Path= de la extensión de marcado solo se puede eliminar si es la primera propiedad en la expresión. Para eliminar la parte Path=, es necesario intercambiar las dos propiedades:

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

Aunque las extensiones de marcado XAML suelen estar delimitadas por llaves, también se pueden expresar como elementos de objeto:

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

En este ejemplo, las propiedades Source y Path son atributos XAML normales: los valores aparecen entre comillas y los atributos no están separados por una coma. La extensión de marcado x:Reference también se puede convertir en un elemento de objeto:

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

Esta sintaxis no es común, pero a veces es necesaria cuando hay objetos complejos implicados.

En los ejemplos mostrados hasta ahora se establecen las propiedades BindingContext y Source de Binding en una extensión de marcado x:Reference para hacer referencia a otra vista en la página. Estas dos propiedades son de tipo Object, y se pueden establecer en cualquier objeto que incluya propiedades adecuadas para los orígenes de enlace. También puedes establecer la propiedad BindingContext o Source en una extensión de marcado x:Static para hacer referencia al valor de una propiedad estática o un campo, o bien en una extensión de marcado StaticResource para hacer referencia a un objeto almacenado en un diccionario de recursos, o directamente en un objeto, que suele ser una instancia de una clase de modelo de vista.

Nota:

La propiedad BindingContext se puede establecer en un objeto Binding para que las propiedades Source y Path de Binding definan el contexto de enlace.

Herencia del contexto de enlace

Puedes especificar el objeto de origen mediante la propiedad BindingContext o la propiedad Source del objeto Binding. Si se establecen las dos, la propiedad Source de Binding tiene prioridad sobre BindingContext.

Importante

El valor de propiedad BindingContext se hereda a través del árbol visual.

En el ejemplo XAML siguiente se muestra la herencia de contexto de enlace:

<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 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>

En este ejemplo, la propiedad BindingContext de StackLayout se establece en el objeto slider. Label y BoxView heredan este contexto de enlace, y en los dos sus propiedades Rotation se establecen en la propiedad Value del elemento Slider:

Binding context inheritance.