Xamarin.Forms Propiedades enlazables
Las propiedades enlazables amplían la funcionalidad de las propiedades CLR al respaldar una propiedad con un BindableProperty
tipo, en lugar de respaldar una propiedad con un campo. El propósito de las propiedades enlazables es proporcionar un sistema de propiedades que admita el enlace de datos, los estilos, las plantillas y los valores establecidos mediante 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:
- Actuar 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.
- Validar el valor de la propiedad.
- Supervisión de cambios en las propiedades.
Algunos ejemplos de Xamarin.Forms propiedades enlazables son Label.Text
, Button.BorderRadius
y StackLayout.Orientation
. Cada propiedad enlazable tiene un campo de tipo BindableProperty
correspondiente public static readonly
que se expone en la misma clase y que es el identificador de la propiedad 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:
- Cree una
BindableProperty
instancia con una de las sobrecargas delBindableProperty.Create
método . - Defina descriptores de acceso de propiedad para la
BindableProperty
instancia.
Todas las BindableProperty
instancias deben crearse en el subproceso de la 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, BindableProperty
se puede acceder a las instancias desde otros subprocesos serializando el subproceso de interfaz de usuario con el Device.BeginInvokeOnMainThread
método .
Creación de una propiedad
Para crear una BindableProperty
instancia, la clase contenedora debe derivar de la BindableObject
clase . Sin embargo, la BindableObject
clase es alta en la jerarquía de clases, por lo que la mayoría de las clases usadas para la funcionalidad de la interfaz de usuario 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 una de las sobrecargas del BindableProperty.Create
método. La declaración debe estar dentro del cuerpo de la BindableObject
clase derivada, pero fuera de cualquier definición de miembro.
Como mínimo, se debe especificar un identificador al crear un BindableProperty
, junto con los parámetros siguientes:
- Nombre del objeto
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 no se establece y puede ser diferente del valor predeterminado para el tipo de la propiedad. El valor predeterminado se restaurará cuando se llame al
ClearValue
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 Create
método , con "Property" anexado a él.
En el código siguiente se 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 EventNameProperty
, de tipo string
. La propiedad es propiedad de la EventToCommandBehavior
clase y tiene un valor predeterminado de null
.
Opcionalmente, al crear una BindableProperty
instancia, se pueden 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 del origen al destino.
- Delegado de validación que se invocará cuando se establezca el valor de la propiedad. Para obtener más información, consulte Devoluciones de llamada de validación.
- Delegado cambiado de propiedad que se invocará cuando el valor de la 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 la propiedad. Este delegado tiene la misma firma que el delegado cambiado por la propiedad.
- Delegado de valor de coerce que se invocará cuando el valor de la propiedad haya cambiado. Para obtener más información, consulte Devoluciones de llamada de valor de Coerce.
Func
que se usa para inicializar un valor de propiedad predeterminado. Para obtener más información, consulte Creación de un valor predeterminado con func.
Creación de descriptores de acceso
Los descriptores de acceso de propiedad son necesarios para usar la sintaxis de propiedad para tener acceso a una propiedad enlazable. El Get
descriptor de acceso debe devolver el valor contenido en la propiedad enlazable correspondiente. Esto se puede lograr llamando al GetValue
método , pasando el identificador de propiedad enlazable en el que se va a obtener el valor y, a continuación, convirtiendo el resultado en el tipo necesario. El Set
descriptor de acceso debe establecer el valor de la propiedad enlazable correspondiente. Esto se puede lograr llamando al SetValue
método , 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 descriptores de acceso para la EventName
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, consulta 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 en el 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 EventName
propiedad 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 BindableProperty
instancia, hay varios parámetros opcionales que se pueden establecer para habilitar escenarios avanzados de propiedades enlazables. En esta sección se exploran estos escenarios.
Detección de cambios de propiedad
Un static
método de devolución de llamada cambiado por la propiedad se puede registrar con una propiedad enlazable especificando el propertyChanged
parámetro para el BindableProperty.Create
método . 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 EventName
propiedad enlazable registra el OnEventNameChanged
método como un método de devolución de llamada cambiado 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 BindableObject
parámetro se usa para indicar qué instancia de la clase propietaria ha notificado un cambio y los valores de los dos object
parámetros representan los valores antiguos y nuevos de la propiedad enlazable.
Devoluciones de llamada de validación
Un static
método de devolución de llamada de validación se puede registrar con una propiedad enlazable especificando el validateValue
parámetro para el BindableProperty.Create
método . 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 Angle
propiedad enlazable registra el IsValidValue
método como un método de devolución 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 true
si el valor es válido para la propiedad; de lo contrario false
, . Se producirá una excepción si una devolución de llamada de validación devuelve false
, que el desarrollador debe controlar. Un uso típico de un método de devolución de llamada de validación restringe los valores de enteros o dobles cuando se establece la propiedad enlazable. Por ejemplo, el IsValidValue
método comprueba que el valor de la propiedad es un double
valor comprendido entre 0 y 360.
Devoluciones de llamada de valor de coerce
Un static
método de devolución de llamada de valor de coerce se puede registrar con una propiedad enlazable especificando el coerceValue
parámetro para el BindableProperty.Create
método . El método de devolución de llamada especificado se invocará cuando cambie el valor de la propiedad enlazable.
Importante
El BindableObject
tipo tiene un CoerceValue
método al que se puede llamar para forzar una reevaluación del valor de su BindableProperty
argumento invocando su devolución de llamada de valor de coerce.
Las devoluciones de llamada de valor de coerce 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 coerce 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 Angle
propiedad enlazable registra el CoerceAngle
método como método de devolución de llamada de valor de coerce:
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 CoerceAngle
método comprueba el valor de la MaximumAngle
propiedad y, si el valor de la Angle
propiedad es mayor que él, convierte el valor en el valor de la MaximumAngle
propiedad. Además, cuando la propiedad cambia la MaximumAngle
devolución de llamada del valor de coerce se invoca en la Angle
propiedad llamando al CoerceValue
método .
Creación de un valor predeterminado con un Func
Func
Se puede usar para inicializar el valor predeterminado de una propiedad enlazable, como se 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 un Func
objeto que invoca el Device.GetNamedSize
método para devolver un double
que representa el tamaño con nombre de la fuente que se usa en una Label
en la plataforma nativa.