Resumen del capítulo 16. Enlace de datos

Nota:

Este libro se publicó en la primavera de 2016 y no se ha actualizado desde entonces. Gran parte del libro sigue siendo útil, pero algunos de los materiales están anticuados y algunos temas ya no son completamente correctos o completos.

Los programadores a menudo se encuentran escribiendo controladores de eventos que detectan cuándo ha cambiado una propiedad de un objeto, y lo usan para cambiar el valor de una propiedad en otro objeto. Este proceso se puede automatizar con la técnica del enlace de datos. Los enlaces de datos se definen normalmente en XAML y pasan a formar parte de la definición de la interfaz de usuario.

A menudo, estos enlaces de datos conectan objetos de la interfaz de usuario a los datos subyacentes. Se trata de una técnica que se explora con mayor profundidad en el Capítulo 18. MVVM. Sin embargo, los enlaces de datos también pueden conectar dos o más elementos de la interfaz de usuario. La mayoría de los ejemplos anteriores de enlace de datos de este capítulo demuestran esta técnica.

Conceptos básicos del enlace

Varias propiedades, métodos y clases están implicados en el enlace de datos:

Las dos clases siguientes admiten las extensiones de marcado XAML para los enlaces:

Hay dos interfaces implicadas en el enlace de datos:

  • INotifyPropertyChanged en el espacio de nombres System.ComponentModel sirve para implementar la notificación cuando cambia una propiedad.
  • IValueConverter se utiliza para definir las clases pequeñas que convierten los valores de un tipo a otro en los enlaces de datos.

Un enlace de datos conecta dos propiedades del mismo objeto, o (más comúnmente) dos objetos diferentes. Estas dos propiedades se denominan origen y destino. Normalmente, un cambio en la propiedad de origen hace que se produzca un cambio en la propiedad de destino, pero a veces se invierte la dirección. En cualquier caso:

Una clase que implementa INotifyPropertyChanged activa un evento PropertyChanged cuando una propiedad cambia de valor. BindableObject implementa INotifyPropertyChanged y activa automáticamente un evento PropertyChanged cuando una propiedad respaldada por BindableProperty cambia valores, pero puede escribir sus propias clases que implementan INotifyPropertyChanged sin que se deriven de BindableObject.

Código y XAML

En el ejemplo OpacityBindingCode se muestra cómo establecer un enlace de datos en el código:

  • El origen es la propiedad Value de Slider.
  • El destino es la propiedad Opacity de Label.

Los dos objetos se conectan estableciendo el BindingContext del objeto Label en el objeto Slider. Las dos propiedades se conectan llamando a un método de extensión SetBinding en el Label que hace referencia a la propiedad enlazable OpacityProperty y la propiedad Value de Slider expresada como una cadena.

La manipulación de la Slider provoca que Label aparezca y desaparezca gradualmente de la vista.

El programa OpacityBindingXaml es el mismo con el enlace de datos establecido en XAML. BindingContext de Label se establece en una extensión de marcado de x:Reference que hace referencia a Slider, y la propiedad Opacity de Label se establece en la extensión de marcado Binding con su propiedad Path que hace referencia a la propiedad Value de Slider.

Source y BindingContext

En el ejemplo BindingSourceCode se muestra un enfoque alternativo en el código. Para crear un objeto Binding, establezca la propiedad Source en el objeto Slider y la propiedad Path en "Value". A continuación, se llama al método SetBinding de BindableObject en el objeto Label.

También se podría haber utilizado el constructor Binding para definir el objeto Binding.

En el ejemplo BindingSourceXaml se muestra la técnica comparable en XAML. La propiedad Opacity de Label se establece en una extensión de marcado de Binding con Path establecido en la propiedad Value y Source establecida en una extensión de marcado x:Reference insertada.

En resumen, hay dos maneras de hacer referencia al objeto de origen de enlace:

  • A través de la propiedad BindingContext del destino.
  • A través de la propiedad Source del propio objeto Binding.

Si se especifican ambos, la segunda tiene prioridad. La ventaja de la BindingContext es que se propaga a través del árbol visual. Esto es muy útil si varias propiedades de destino están enlazadas al mismo objeto de origen.

El programa WebViewDemo muestra esta técnica con el elemento WebView. Dos elementos Button para navegar hacia atrás y hacia delante heredan un objeto BindingContext de su elemento primario que hace referencia a WebView. Las propiedades de IsEnabled de los dos botones tienen extensiones de marcado de Binding simples que tienen como destino las propiedades IsEnabled del botón basadas en la configuración de las propiedades CanGoBack y CanGoForward de solo lectura de WebView.

Modo de enlace

Establezca la propiedad Mode de Binding en un miembro de la enumeración BindingMode:

  • OneWay para que los cambios en la propiedad de origen afecten al destino.
  • OneWayToSource para que los cambios en la propiedad de destino afecten al origen.
  • TwoWay para que los cambios en el origen y el destino se afecten entre sí.
  • Default para usar el valor DefaultBindingMode especificado cuando se creó el valor BindableProperty de destino. Si no se especifica ninguno, el valor predeterminado es OneWay para las propiedades normales enlazables y OneWayToSource para las propiedades enlazables de solo lectura.

Nota:

La enumeración de BindingMode ahora también incluye OnTime para aplicar un enlace solo cuando cambia el contexto de enlace y no cuando cambia la propiedad de origen.

Las propiedades que es probable que sean los destinos de los enlaces de datos en escenarios de MVVM generalmente tienen un valor DefaultBindingMode de TwoWay. Dichos componentes son:

  • Propiedad Value de Slider y Stepper
  • Propiedad IsToggled de Switch
  • Propiedad Text de Entry, Editor y SearchBar.
  • Propiedad Date de DatePicker
  • Propiedad Time de TimePicker

En el ejemplo BindingModes se muestran los cuatro modos de enlace con un enlace de datos, donde el destino es la propiedad FontSize de un elemento Label y el origen es la propiedad Value de un elemento Slider. Esto permite que cada Slider controle el tamaño de fuente del Label correspondiente. Sin embargo, los elementos Slider no se inicializan porque el DefaultBindingMode de la propiedad FontSize es OneWay.

El ejemplo ReverseBinding establece los enlaces en la propiedad Value del Slider que hace referencia a la propiedad FontSize de cada Label. Parece que va para atrás, pero funciona mejor al inicializar los elementos Slider porque la propiedad Value de Slider tiene un DefaultBindingMode de TwoWay.

Captura de pantalla triple de enlace inverso

Esto es análogo a la forma en que se definen los enlaces en MVVM, y usará este tipo de enlace con frecuencia.

Formato de cadena

Cuando la propiedad de destino es de tipo string, puede usar la propiedad StringFormat definida por BindingBase para convertir el origen en string. Establezca la propiedad StringFormat en una cadena de formato de .NET que se usaría con el formato String.Format estático para mostrar el objeto. Al utilizar esta cadena de formato dentro de una extensión de marcado, inclúyala entre comillas simples para que las llaves no se confundan en el caso de una extensión de marcado insertada.

En el ejemplo ShowViewValues se muestra cómo utilizar StringFormat en XAML.

En el ejemplo WhatSizeBindings se demuestra cómo mostrar el tamaño de la página con enlaces a las propiedades Width y Height de ContentPage.

¿Por qué se denomina "Path"?

La propiedad Path de Binding se llama así porque puede ser una serie de propiedades e indexadores separados por puntos. En el ejemplo BindingPathDemos se muestran varios ejemplos.

Enlace de convertidores de valores

Cuando las propiedades de origen y de destino de un enlace son tipos diferentes, puede aplicar conversiones a los tipos mediante un convertidor de enlace. Se trata de una clase que implementa la interfaz IValueConverter y contiene dos métodos: Convert para convertir el origen en destino y ConvertBack para convertir el destino en origen.

La clase IntToBoolConverter de la biblioteca Xamarin.FormsBook.Toolkit es un ejemplo de cómo convertir int en bool. Se demuestra en el ejemplo ButtonEnabler, que solo habilita Button si se ha escrito al menos un carácter en Entry.

La clase BoolToStringConverter convierte bool en string y define dos propiedades para especificar qué texto se debe devolver para los valores false y true. BoolToColorConverter es similar. En el ejemplo SwitchText se muestra el uso de estos dos convertidores para mostrar textos distintos en diferentes colores basados en una configuración de Switch.

El valor BoolToObjectConverter genérico puede reemplazar a BoolToStringConverter y BoolToColorConverter y servir como convertidor generalizado de bool a objeto de cualquier tipo.

Enlaces y vistas personalizadas

Puede simplificar los controles personalizados mediante enlaces de datos. El archivo de código NewCheckBox.cs define las propiedades Text, TextColor, FontSize, FontAttributes y IsChecked, pero no tiene ninguna lógica para los objetos visuales del control. En su lugar, el archivo NewCheckBox.cs.xaml contiene todo el marcado de los objetos visuales del control a través de enlaces de datos en los elementos Label basados en las propiedades definidas en el archivo de código subyacente.

En el ejemplo NewCheckBoxDemo se muestra el control personalizado de NewCheckBox.