Compartir a través de


Modo de enlace

Browse sample. Examinar la muestra.

Todas las propiedades enlazables de .NET Multi-platform App UI (.NET MAUI) tienen un modo de enlace predeterminado que se establece cuando se crea la propiedad enlazable, y que está disponible en la propiedad DefaultBindingMode del objeto BindableProperty. Este modo de enlace predeterminado indica el modo en vigor cuando esa propiedad es un destino de enlace de datos. El modo de enlace predeterminado para la mayoría de las propiedades como Rotation, Scale y Opacity es OneWay. Cuando estas propiedades son destinos de enlace de datos, la propiedad de destino se establece desde el origen.

En el ejemplo siguiente se muestra un enlace de datos definido en Slider:

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

En este ejemplo, Label es el origen de enlace de datos y Slider es el destino. El enlace hace referencia a la propiedad Opacity de Label, que tiene un valor predeterminado de 1. Como cabría esperar, Slider se inicializa en el valor 1 a partir del valor inicial Opacity de Label. Esto se muestra en la captura de pantalla siguiente.

Reverse binding.

Además, Slider continúa funcionando. Esto se debe a que el modo de enlace predeterminado para la propiedad Value de Slider es TwoWay. Esto significa que cuando la propiedad Value es un destino de enlace de datos, el destino se establece desde el origen, pero el origen también se establece desde el destino. Esto es lo que permite que Slider se establezca en el valor inicial Opacity.

Nota:

Las propiedades enlazables no señalan un cambio de propiedad a menos que la propiedad cambie realmente. Esto evita un bucle infinito.

Si el modo de enlace predeterminado en la propiedad de destino no es adecuado para un enlace de datos concreto, es posible reemplazarlo si se establece la propiedad Mode de Binding (o la propiedad Mode de la extensión de marcado Binding) en uno de los miembros de la enumeración BindingMode.

  • Default
  • TwoWay: los datos van en ambas direcciones entre el origen y el destino
  • OneWay: los datos van del origen al destino
  • OneWayToSource: los datos van del destino al origen
  • OneTime: los datos van del origen al destino, pero solo cuando cambia BindingContext

Enlaces bidireccionales

La mayoría de las propiedades enlazables tienen un modo de enlace predeterminado de OneWay, pero algunas propiedades tienen un modo de enlace predeterminado de TwoWay, incluidas las siguientes:

Estas propiedades se definen como TwoWay, porque cuando los enlaces de datos se usan con el patrón Modelo-Vista-Modelo de vista (MVVM), la clase de modelo de vista es el origen del enlace de datos y la vista, que consta de vistas como Slider, son destinos de enlace de datos. Los enlaces de MVVM se parecen al ejemplo anterior, porque es muy probable que quieras que cada vista de la página se inicialice con el valor de la propiedad correspondiente en el modelo de vista, pero los cambios en la vista también deberían afectar a la propiedad de modelo de vista.

Enlaces unidireccionales al origen

Las propiedades enlazables de solo lectura tienen un modo de enlace predeterminado de OneWayToSource. Por ejemplo, la propiedad SelectedItem de ListView tiene un modo de enlace predeterminado de OneWayToSource. La razón es que el resultado de un enlace en la propiedad SelectedItem debe ser el establecimiento del origen de enlace.

Enlaces de un solo uso

Las propiedades de destino con un modo de enlace de OneTime solo se actualizan cuando cambia el contexto de enlace. Para los enlaces en estas propiedades de destino, esto simplifica la infraestructura de enlace ya que no es necesario supervisar los cambios en las propiedades de origen.

Varias propiedades enlazables tienen un modo de enlace predeterminado de OneTime, que incluye la propiedad IsTextPredictionEnabled de Entry.

Modelos de vista y notificaciones de cambio de propiedad

Cuando se usa un modelo de vista en un enlace de datos, el modelo de vista es el origen de enlace de datos. El modelo de vista no define propiedades enlazables, pero implementa un mecanismo de notificación que permite que la infraestructura de enlace reciba una notificación cuando cambia el valor de una propiedad. Este mecanismo de notificación es la interfaz de INotifyPropertyChanged, que define un único evento denominado PropertyChanged. Una clase que implemente esta interfaz normalmente desencadena el evento cuando cambia el valor de una de sus propiedades públicas. No es necesario desencadenar el evento si la propiedad no cambia nunca. La interfaz INotifyPropertyChanged también se implementa mediante BindableObject y se desencadena un evento PropertyChanged cada vez que una propiedad enlazable cambia de valor.

En el ejemplo siguiente, los enlaces de datos te permiten seleccionar un color mediante tres elementos Slider para el matiz, la saturación y la luminosidad.

public class HslColorViewModel : INotifyPropertyChanged
{
    Color color;
    string name;
    float hue;
    float saturation;
    float luminosity;

    public event PropertyChangedEventHandler PropertyChanged;

    public float Hue
    {
        get
        {
            return hue;
        }
        set
        {
            if (hue != value)
            {
                Color = Color.FromHsla(value, saturation, luminosity);
            }
        }
    }

    public float Saturation
    {
        get
        {
            return saturation;
        }
        set
        {
            if (saturation != value)
            {
                Color = Color.FromHsla(hue, value, luminosity);
            }
        }        
    }

    public float Luminosity
    {
        get
        {
            return luminosity;
        }
        set
        {
            if (luminosity != value)
            {
                Color = Color.FromHsla(hue, saturation, value);
            }
        }
    }

    public Color Color
    {
        get
        {
            return color;
        }
        set
        {
            if (color != value)
            {
                color = value;
                hue = color.GetHue();
                saturation = color.GetSaturation();
                luminosity = color.GetLuminosity();
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Hue"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Saturation"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Luminosity"));
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Color"));

                Name = NamedColor.GetNearestColorName(color);
            }
        }
    }

    public string Name
    {
        get
        {
            return name;
        }
        private set
        {
            if (name != value)
            {
                name = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Name"));
            }
        }
    }
}

En este ejemplo, la clase HslColorViewModel define las propiedades: Hue, Saturation, Luminosity, Color y Name. Cuando cambia el valor de cualquiera de los tres componentes de color, se vuelve a calcular la propiedad Color y se desencadenan eventos PropertyChanged para las cuatro propiedades: Cuando cambia la propiedad Color, el método estático GetNearestColorName de la clase NamedColor obtiene el color con nombre más cercano y establece la propiedad Name.

Cuando se establece un modelo de vista como un origen de enlace, la infraestructura de enlace adjunta un controlador al evento PropertyChanged. De esta manera, el enlace puede recibir una notificación de cambios en las propiedades y, después, puede establecer las propiedades de destino a partir de los valores cambiados. Pero cuando una propiedad de destino (o la definición Binding en una propiedad de destino) tiene un elemento BindingMode de tipo OneTime, no es necesario que la infraestructura de enlace adjunte un controlador al evento PropertyChanged. La propiedad de destino solo se actualiza cuando cambia BindingContext y no cuando cambia la propiedad de origen.

El código XAML siguiente consume HslColorViewModel:

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.SimpleColorSelectorPage">
    <ContentPage.BindingContext>
        <local:HslColorViewModel Color="MediumTurquoise" />
    </ContentPage.BindingContext>

    <ContentPage.Resources>
        <Style TargetType="Slider">
            <Setter Property="VerticalOptions" Value="CenterAndExpand" />
        </Style>
    </ContentPage.Resources>

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <BoxView Color="{Binding Color}"
                 Grid.Row="0" />
        <StackLayout Grid.Row="1"
                     Margin="10, 0">
            <Label Text="{Binding Name}"
                   HorizontalTextAlignment="Center" />
            <Slider Value="{Binding Hue}" />
            <Slider Value="{Binding Saturation}" />
            <Slider Value="{Binding Luminosity}" />
        </StackLayout>
    </Grid>
</ContentPage>

En este ejemplo, se crea una instancia de HslColorViewModel y se establece la propiedad Color, y se establece como BindingContext de la página. Los elementos BoxView, Label y tres vistas Slider heredan el contexto de enlace del elemento ContentPage. Todas estas vistas son destinos de enlace que hacen referencia a las propiedades de origen en el modelo de vista. Para la propiedad Color de BoxView, y la propiedad Text de Label, los enlaces de datos son OneWay: las propiedades de la vista se establecen a partir de las propiedades del modelo de vista. Sin embargo, la propiedad Value de Slider usa un modo de enlace TwoWay. Esto permite que cada Slider se establezca a partir del modelo de vista, y también que el modelo de vista se establezca a partir de cada Slider.

Cuando se ejecuta por primera vez el ejemplo, BoxView, Label y los tres elementos Slider están establecidos a partir del modelo de vista en función de la propiedad Color inicial establecida cuando se creó la instancia del modelo de vista.

Simple color selector.

A medida que se manipulan los controles deslizantes, BoxView y Label se actualizan del modo correspondiente.

Reemplazo del modo de enlace

Si el modo de enlace en la propiedad de destino se puede reemplazar estableciendo la propiedad Mode de Binding (o la propiedad Mode de la extensión de marcado Binding) en uno de los miembros de la enumeración BindingMode.

Sin embargo, el establecimiento de la propiedad Mode no siempre produce el resultado esperado. Por ejemplo, en el ejemplo siguiente, establecer la propiedad Mode en TwoWay no funciona como podrías esperar:

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

En este ejemplo, se podría esperar que Slider se inicializara en el valor inicial de la propiedad Scale, que es 1, pero no es lo que sucede. Cuando se inicializa un enlace TwoWay, primero se establece el destino a partir del origen, lo que significa que la propiedad Scale se establece en el valor predeterminado de Slider de 0. Cuando se configura el enlace TwoWay en el elemento Slider, el elemento Slider se establece inicialmente a partir del origen.

Como alternativa, puedes establecer el modo de enlace en OneWayToSource:

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

Ahora se inicializa Slider en 1 (el valor predeterminado de Scale) pero la manipulación de Slider no afecta a la propiedad Scale.

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.

Una aplicación muy útil del reemplazo del modo de enlace predeterminado con un modo de enlace TwoWay implica la propiedad SelectedItem de ListView. El modo de enlace predeterminado es OneWayToSource. Cuando se establece un enlace de datos en la propiedad SelectedItem para hacer referencia a una propiedad de origen en un modelo de vista, esa propiedad de origen se establece a partir de la selección ListView. Pero en algunas circunstancias, es posible que te interese que también se inicialice ListView a partir del modelo de vista.

Importante

El modo de enlace predeterminado puede variar de control a control y se establece cuando se crea la propiedad enlazable. Está disponible de la propiedad DefaultBindingMode del objeto BindableProperty.