Xamarin.Forms Propiedades enlazables

Descargar ejemplo. Descarga del ejemplo

Las propiedades enlazables amplían la funcionalidad de las propiedades CLR mediante la copia de seguridad de una propiedad con un tipo, en lugar de hacer una copia de seguridad BindableProperty de una propiedad con un campo . El propósito de las propiedades enlazables es proporcionar un sistema de propiedades que admita el enlace de datos, estilos, plantillas y valores establecidos a través de relaciones de elementos primarios y secundarios. Además, las propiedades enlazables pueden proporcionar valores predeterminados, validación de valores de propiedad y devoluciones de llamada que supervisan los cambios de propiedad.

Las propiedades deben implementarse como propiedades enlazables para admitir una o varias de las siguientes características:

  • Actúa como una propiedad de destino válida para el enlace de datos.
  • Establecer la propiedad a través de un estilo.
  • Proporcionar un valor de propiedad predeterminado diferente del predeterminado para el tipo de la propiedad.
  • Validación del valor de la propiedad.
  • Supervisión de los cambios de propiedad.

Algunos ejemplos Xamarin.Forms de propiedades enlazables Label.Text son , Button.BorderRadius y StackLayout.Orientation . Cada propiedad enlazable tiene un campo de tipo correspondiente que se expone en la misma clase y que es el public static readonly identificador de la propiedad BindableProperty enlazable. Por ejemplo, el identificador de propiedad enlazable correspondiente para la Label.Text propiedad es Label.TextProperty .

Creación de una propiedad enlazable

El proceso para crear una propiedad enlazable es el siguiente:

  1. Cree una BindableProperty instancia con una de las BindableProperty.Create sobrecargas de método.
  2. Defina los accessors de propiedad para la BindableProperty instancia.

Todas BindableProperty las instancias deben crearse en el subproceso de interfaz de usuario. Esto significa que solo el código que se ejecuta en el subproceso de interfaz de usuario puede obtener o establecer el valor de una propiedad enlazable. Sin embargo, se puede acceder a las instancias desde otros subprocesos mediante BindableProperty la serialización al subproceso de interfaz de usuario con el Device.BeginInvokeOnMainThread método .

Creación de una propiedad

Para crear una BindableProperty instancia de , la clase contenedora debe derivarse de la clase BindableObject . Sin embargo, la clase es alta en la jerarquía de clases, por lo que la mayoría de las clases usadas para la funcionalidad de interfaz de usuario BindableObject admiten propiedades enlazables.

Se puede crear una propiedad enlazable declarando una public static readonly propiedad de tipo BindableProperty . La propiedad enlazable debe establecerse en el valor devuelto de uno de los [ BindableProperty.Create ](xref: Xamarin.Forms . BindableProperty.Create(System.String,System.Type,System.Type,System.Object, Xamarin.Forms . BindingMode, Xamarin.Forms . BindableProperty.ValidateValueDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangedDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangingDelegate, Xamarin.Forms . BindableProperty.CoerceValueDelegate, Xamarin.Forms . BindableProperty.CreateDefaultValueDelegate)) sobrecargas del método. La declaración debe estar dentro del cuerpo BindableObject de la clase derivada, pero fuera de cualquier definición de miembro.

Como mínimo, se debe especificar un identificador al crear BindableProperty un , junto con los parámetros siguientes:

  • Nombre de BindableProperty .
  • Tipo de la propiedad.
  • Tipo del objeto propietario.
  • Valor predeterminado de la propiedad. Esto garantiza que la propiedad siempre devuelve un valor predeterminado determinado cuando está sin establecer y puede ser diferente del valor predeterminado para el tipo de la propiedad. El valor predeterminado se restaurará cuando [ ClearValue ](xref: Xamarin.Forms . BindableObject.ClearValue( Xamarin.Forms . BindableProperty)) se llama al método en la propiedad enlazable.

Importante

La convención de nomenclatura para las propiedades enlazables es que el identificador de propiedad enlazable debe coincidir con el nombre de propiedad especificado en el método , con Create "Property" anexado.

El código siguiente muestra un ejemplo de una propiedad enlazable, con un identificador y valores para los cuatro parámetros necesarios:

public static readonly BindableProperty EventNameProperty =
  BindableProperty.Create ("EventName", typeof(string), typeof(EventToCommandBehavior), null);

Esto crea una BindableProperty instancia denominada , de tipo EventNameProperty string . La propiedad es propiedad de la EventToCommandBehavior clase y tiene un valor predeterminado de null .

Opcionalmente, al crear una instancia, se pueden BindableProperty especificar los parámetros siguientes:

  • Modo de enlace. Se usa para especificar la dirección en la que se propagarán los cambios de valor de propiedad. En el modo de enlace predeterminado, los cambios se propagarán desde el origen al de destino.
  • Delegado de validación que se invocará cuando se establezca el valor de propiedad. Para obtener más información, vea Devoluciones de llamada de validación.
  • Delegado de propiedad modificada que se invocará cuando el valor de propiedad haya cambiado. Para obtener más información, vea Detectar cambios de propiedad.
  • Delegado de cambio de propiedad que se invocará cuando cambie el valor de propiedad. Este delegado tiene la misma firma que el delegado cambiado de propiedad.
  • Delegado de valor de coerción que se invocará cuando el valor de propiedad haya cambiado. Para obtener más información, vea Coerce value callbacks.
  • que Func se usa para inicializar un valor de propiedad predeterminado. Para obtener más información, vea Crear un valor predeterminado con un func.

Creación de los accessors

Los accessors de propiedad deben usar la sintaxis de propiedad para tener acceso a una propiedad enlazable. El accessor debe devolver el valor contenido en Get la propiedad enlazable correspondiente. Esto se puede lograr llamando a [ GetValue ](xref: Xamarin.Forms . BindableObject.GetValue( Xamarin.Forms . BindableProperty)), pasando el identificador de propiedad enlazable en el que se va a obtener el valor y, a continuación, convierte el resultado al tipo necesario. El Set accessor debe establecer el valor de la propiedad enlazable correspondiente. Esto se puede lograr llamando a [ SetValue ](xref: Xamarin.Forms . BindableObject.SetValue( Xamarin.Forms . Método BindableProperty,System.Object)), pasando el identificador de propiedad enlazable en el que se va a establecer el valor y el valor que se va a establecer.

En el ejemplo de código siguiente se muestran los accessors de EventName la propiedad enlazable:

public string EventName
{
  get { return (string)GetValue (EventNameProperty); }
  set { SetValue (EventNameProperty, value); }
}

Consumo de una propiedad enlazable

Una vez creada una propiedad enlazable, se puede consumir desde XAML o código. En XAML, esto se logra declarando un espacio de nombres con un prefijo, con la declaración de espacio de nombres que indica el nombre del espacio de nombres CLR y, opcionalmente, un nombre de ensamblado. Para obtener más información, vea Espacios de nombres XAML.

En el ejemplo de código siguiente se muestra un espacio de nombres XAML para un tipo personalizado que contiene una propiedad enlazable, que se define dentro del mismo ensamblado que el código de aplicación que hace referencia al tipo personalizado:

<ContentPage ... xmlns:local="clr-namespace:EventToCommandBehavior" ...>
  ...
</ContentPage>

La declaración de espacio de nombres se usa al establecer la propiedad EventName enlazable, como se muestra en el siguiente ejemplo de código XAML:

<ListView ...>
  <ListView.Behaviors>
    <local:EventToCommandBehavior EventName="ItemSelected" ... />
  </ListView.Behaviors>
</ListView>

El código de C# equivalente se muestra en el ejemplo de código siguiente:

var listView = new ListView ();
listView.Behaviors.Add (new EventToCommandBehavior
{
  EventName = "ItemSelected",
  ...
});

Escenarios avanzados

Al crear una instancia de , hay una serie de parámetros opcionales que se pueden establecer BindableProperty para habilitar escenarios avanzados de propiedades enlazables. En esta sección se exploran estos escenarios.

Detección de cambios de propiedad

Un método de devolución de llamada modificado por la propiedad se puede registrar con una propiedad enlazable especificando el parámetro static propertyChanged para [ BindableProperty.Create ](xref: Xamarin.Forms . BindableProperty.Create(System.String,System.Type,System.Type,System.Object, Xamarin.Forms . BindingMode, Xamarin.Forms . BindableProperty.ValidateValueDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangedDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangingDelegate, Xamarin.Forms . BindableProperty.CoerceValueDelegate, Xamarin.Forms . Método BindableProperty.CreateDefaultValueDelegate)). El método de devolución de llamada especificado se invocará cuando cambie el valor de la propiedad enlazable.

En el ejemplo de código siguiente se muestra cómo la propiedad EventName enlazable registra el método como un método de devolución de llamada OnEventNameChanged modificado por propiedad:

public static readonly BindableProperty EventNameProperty =
  BindableProperty.Create (
    "EventName", typeof(string), typeof(EventToCommandBehavior), null, propertyChanged: OnEventNameChanged);
...

static void OnEventNameChanged (BindableObject bindable, object oldValue, object newValue)
{
  // Property changed implementation goes here
}

En el método de devolución de llamada de cambio de propiedad, el parámetro se usa para indicar qué instancia de la clase propietaria ha notificado un cambio y los valores de los dos parámetros representan los valores antiguos y nuevos de la propiedad BindableObject object enlazable.

Devoluciones de llamada de validación

Un método de devolución de llamada de validación se puede registrar con una propiedad enlazable especificando el parámetro static validateValue para [ BindableProperty.Create ](xref: Xamarin.Forms . BindableProperty.Create(System.String,System.Type,System.Type,System.Object, Xamarin.Forms . BindingMode, Xamarin.Forms . BindableProperty.ValidateValueDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangedDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangingDelegate, Xamarin.Forms . BindableProperty.CoerceValueDelegate, Xamarin.Forms . Método BindableProperty.CreateDefaultValueDelegate)). El método de devolución de llamada especificado se invocará cuando se establezca el valor de la propiedad enlazable.

En el ejemplo de código siguiente se muestra cómo la propiedad enlazable registra el método como un método de devolución Angle IsValidValue de llamada de validación:

public static readonly BindableProperty AngleProperty =
  BindableProperty.Create ("Angle", typeof(double), typeof(HomePage), 0.0, validateValue: IsValidValue);
...

static bool IsValidValue (BindableObject view, object value)
{
  double result;
  bool isDouble = double.TryParse (value.ToString (), out result);
  return (result >= 0 && result <= 360);
}

Las devoluciones de llamada de validación se proporcionan con un valor y deben devolver si el valor es válido para la propiedad ; en caso true contrario, false . Se producirá una excepción si una devolución de llamada de validación devuelve , que false debe ser controlada por el desarrollador. Un uso típico de un método de devolución de llamada de validación es restringir los valores de enteros o doubles cuando se establece la propiedad enlazable. Por ejemplo, el IsValidValue método comprueba que el valor de propiedad está dentro del intervalo de double 0 a 360.

Devoluciones de llamada de valor de coerción

Un método de devolución de llamada de valor de coerción se puede registrar con una propiedad enlazable especificando el parámetro static coerceValue para [ BindableProperty.Create ](xref: Xamarin.Forms . BindableProperty.Create(System.String,System.Type,System.Type,System.Object, Xamarin.Forms . BindingMode, Xamarin.Forms . BindableProperty.ValidateValueDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangedDelegate, Xamarin.Forms . BindableProperty.BindingPropertyChangingDelegate, Xamarin.Forms . BindableProperty.CoerceValueDelegate, Xamarin.Forms . Método BindableProperty.CreateDefaultValueDelegate)). El método de devolución de llamada especificado se invocará cuando cambie el valor de la propiedad enlazable.

Importante

El tipo tiene un método al que se puede llamar para forzar una reevaluación del valor de su argumento, invocando su devolución de llamada de valor de BindableObject CoerceValue BindableProperty coerción.

Las devoluciones de llamada de valor de coerción se usan para forzar una reevaluación de una propiedad enlazable cuando cambia el valor de la propiedad. Por ejemplo, se puede usar una devolución de llamada de valor de coerción para asegurarse de que el valor de una propiedad enlazable no es mayor que el valor de otra propiedad enlazable.

En el ejemplo de código siguiente se muestra cómo la propiedad enlazable registra el método como un método de devolución de llamada de Angle CoerceAngle valor de coerción:

public static readonly BindableProperty AngleProperty = BindableProperty.Create (
  "Angle", typeof(double), typeof(HomePage), 0.0, coerceValue: CoerceAngle);
public static readonly BindableProperty MaximumAngleProperty = BindableProperty.Create (
  "MaximumAngle", typeof(double), typeof(HomePage), 360.0, propertyChanged: ForceCoerceValue);
...

static object CoerceAngle (BindableObject bindable, object value)
{
  var homePage = bindable as HomePage;
  double input = (double)value;

  if (input > homePage.MaximumAngle)
  {
    input = homePage.MaximumAngle;
  }
  return input;
}

static void ForceCoerceValue(BindableObject bindable, object oldValue, object newValue)
{
  bindable.CoerceValue(AngleProperty);
}

El método comprueba el valor de la propiedad y, si el valor de la propiedad es mayor que CoerceAngle MaximumAngle Angle él, coerción el valor al valor MaximumAngle de propiedad. Además, cuando la propiedad cambia, la devolución de llamada del valor de MaximumAngle coerción se invoca en la propiedad mediante una llamada al método Angle CoerceValue .

Creación de un valor predeterminado con un Func

Se puede usar para inicializar el valor predeterminado de una propiedad enlazable, como se Func muestra en el ejemplo de código siguiente:

public static readonly BindableProperty SizeProperty =
  BindableProperty.Create ("Size", typeof(double), typeof(HomePage), 0.0,
  defaultValueCreator: bindable => Device.GetNamedSize (NamedSize.Large, (Label)bindable));

El defaultValueCreator parámetro se establece en que invoca el objeto [ Func Device.GetNamedSize ](xref: Xamarin.Forms . Device.GetNamedSize( Xamarin.Forms . NamedSize,System.Type)) para devolver un que representa el tamaño con nombre de la fuente que se double usa en en la plataforma Label nativa.