Enlaces básicos
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:
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 denominadoslider
. - La extensión de marcado
Binding
enlaza la propiedadRotation
de Label a la propiedadValue
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}" />
Importante
El rendimiento del enlace se puede mejorar mediante enlaces compilados. Para obtener más información, consulta Enlaces compilados.
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: