Resumen del capítulo 23. Desencadenadores y comportamientos

Download SampleDescargar el ejemplo

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 desencadenadores y los comportamientos son similares, ya que ambos están diseñados para usarse en archivos XAML con el fin de simplificar las interacciones de los elementos más allá del uso de los enlaces de datos y para ampliar la funcionalidad de los elementos XAML. Los desencadenadores y los comportamientos casi siempre se usan con objetos visuales de la interfaz de usuario.

Para admitir desencadenadores y comportamientos, tanto VisualElement como Style admiten dos propiedades de colección:

Desencadenadores

Un desencadenador es una condición (un cambio de propiedad o la activación de un evento) que da como resultado una respuesta (otro cambio de propiedad o ejecución de código). La propiedad Triggers de VisualElement y Style es de tipo IList<TriggersBase>. TriggerBase es una clase abstracta de la que derivan cuatro clases selladas:

  • Trigger para respuestas basadas en cambios de propiedad
  • EventTrigger para respuestas basadas en activaciones de eventos
  • DataTrigger para respuestas basadas en enlaces de datos
  • MultiTrigger para respuestas basadas en varios desencadenadores

El desencadenador siempre se establece en el elemento cuya propiedad está cambiando por el desencadenador.

El desencadenador más sencillo

La clase Trigger comprueba si se ha cambiado un valor de propiedad y responde estableciendo otra propiedad del mismo elemento.

Trigger define tres propiedades:

  • Property de tipo BindableProperty
  • Value de tipo Object
  • Setters de tipo IList<SetterBase>, la propiedad de contenido de Trigger

Además, Trigger requiere que se la siguiente propiedad heredada de TriggerBase se establezca en:

  • TargetType para indicar el tipo del elemento con el que está asociado Trigger.

Property y Value componen la condición, y la colección Setters es la respuesta. Cuando el elemento Property indicado tiene el valor indicado por Value, se aplican los objetos Setter de la colección Setters. Cuando Property tiene un valor diferente, se quitan los establecedores. Setter define dos propiedades que son iguales a las dos primeras propiedades de Trigger:

En el ejemplo EntryPop se muestra cómo un Trigger aplicado a un Entry puede aumentar el tamaño de Entry a través de la propiedad Scale cuando la propiedad IsFocused de Entry es true.

Aunque no es común, Trigger se puede establecer en el código, como se muestra en el ejemplo EntryPopCode.

En el ejemplo StyledTriggers se muestra cómo se puede establecer Trigger en Style para que se aplique a varios elementos Entry.

Acciones y animaciones de desencadenadores

También es posible ejecutar un poco de código basado en un desencadenador. Este código puede ser una animación destinada a una propiedad. Una forma habitual es usar EventTrigger, que define dos propiedades:

  • Event de tipo string, el nombre de un evento
  • Actions de tipo IList<TriggerAction>, una lista de acciones que se ejecutarán como respuesta.

Para usar esto, debe escribir una clase que derive de TriggerAction<T>, generalmente TriggerAction<VisualElement>. Puede definir las propiedades de esta clase. Se trata de propiedades de CLR sin formato en lugar de propiedades enlazables porque TriggerAction no se deriva de BindableObject. Debe reemplazar el método Invoke al que se llama cuando se invoca la acción. El argumento es el elemento de destino.

La clase ScaleAction de la biblioteca Xamarin.FormsBook.Toolkit es un ejemplo. Llama a la propiedad ScaleTo para animar la propiedad Scale de un elemento. Dado que una de sus propiedades es de tipo Easing, la clase EasingConverter permite usar los campos estáticos Easing estándar en XAML.

En el ejemplo EntrySwell se muestra cómo invocar ScaleAction desde objetos EventTrigger que supervisan los eventos Focused y Unfocused.

En el ejemplo CustomEasingSwell se muestra cómo definir una función de aceleración personalizada para ScaleAction en un archivo de código subyacente.

También puede invocar acciones mediante Trigger (como se distingue de EventTrigger). Esto requiere que tenga en cuenta que TriggerBase define dos colecciones:

En el ejemplo EnterExitSwell se muestra cómo usar estas colecciones.

Más desencadenadores de eventos

La clase ScaleUpAndDownAction de la biblioteca Xamarin.FormsBook.Toolkit llama a ScaleTo dos veces para escalar y reducir verticalmente. En el ejemplo ButtonGrowth se usa esto con un estilo EventTrigger para proporcionar comentarios visuales cuando se presiona un elemento Button. Esta animación doble también es posible mediante dos acciones en la colección de tipo DelayedScaleAction.

La clase ShiverAction de la biblioteca Xamarin.FormsBook.Toolkit define una acción Shiver personalizable. En el ejemplo ShiverButtonDemo se muestra este comportamiento.

La clase NumericValidationAction de la biblioteca Xamarin.FormsBook.Toolkit está restringida a elementos Entry y establece la propiedad TextColor en rojo si la propiedad Text no es double. En el ejemplo TriggerEntryValidation se muestra este comportamiento.

Desencadenadores de datos

DataTrigger es similar a Trigger, salvo que en lugar de supervisar una propiedad para los cambios de valor, supervisa un enlace de datos. Esto permite que una propiedad de un elemento afecte a una propiedad de otro elemento.

DataTrigger define tres propiedades:

En el ejemplo GenderColors se requiere la biblioteca SchoolOfFineArt y se establecen los colores de los nombres de los alumnos en azul o rosa en función de la propiedad Sex:

Triple screenshot of Gender Colors

En el ejemplo ButtonEnabler se establece la propiedad IsEnabled de Entry en False si la propiedad Length de la propiedad Text de Entry es igual a 0. Observe que la propiedad Text se inicializa en una cadena vacía; de forma predeterminada, es null, y DataTrigger no funcionaría correctamente.

Combinar condiciones en MultiTrigger

MultiTrigger es una colección de condiciones. Cuando todos son true, se aplican los establecedores. La clase define dos propiedades:

Condition es una clase abstracta y tiene dos clases descendientes:

En el ejemplo AndConditions, BoxView solo se colorea cuando se activan cuatro elementos Switch.

En el ejemplo OrConditions se muestra cómo puede convertir BoxView en un color cuando cualquiera de los cuatro elementos Switch está activado. Esto requiere una aplicación de la ley de De Morgan e invertir toda la lógica.

La combinación de la lógica AND y OR no es tan fácil y, por lo general, requiere elementos Switch invisibles para los resultados intermedios. En el ejemplo XorConditions se muestra cómo se puede habilitar Button si uno de dos elementos Entry tiene algún texto escrito, pero no si ambos tienen algún texto escrito.

Comportamientos

Todo lo que puede hacer con un desencadenador, también puede hacerlo con un comportamiento, pero los comportamientos siempre requieren una clase que deriva de Behavior<T> e invalida los dos métodos siguientes:

El argumento es el elemento al que está asociado el comportamiento. Por lo general, el método OnAttachedTo asocia algunos controladores de eventos y OnDetachingFrom los desasocia. Dado que este tipo de clase normalmente guarda algún estado, normalmente no se puede compartir en Style.

El ejemplo BehaviorEntryValidation es similar a TriggerEntryValidation, salvo que usa un comportamiento; la clase NumericValidationBehavior de la biblioteca Xamarin.FormsBook.Toolkit.

Comportamientos con propiedades

Behavior<T> deriva de Behavior, que se deriva de BindableObject, de modo que las propiedades enlazables se pueden definir en un comportamiento. Estas propiedades pueden estar activas en los enlaces de datos.

Esto se muestra en el programa EmailValidationDemo que usa la clase ValidEmailBehavior en la biblioteca Xamarin.FormsBook.Toolkit. ValidEmailBehavior tiene una propiedad enlazable de solo lectura y sirve como origen en los enlaces de datos.

El ejemplo EmailValidationConv utiliza este mismo comportamiento para mostrar otro tipo de indicador para indicar que una dirección de correo electrónico es válida.

El ejemplo EmailValidationTrigger es una variación del ejemplo anterior. ButtonGlide usa DataTrigger en combinación con ese comportamiento.

Alternancia y casillas

Es posible encapsular el comportamiento de un botón de alternancia en una clase, como ToggleBehavior en la biblioteca Xamarin.FormsBook.Toolkit y, a continuación, definir todos los objetos visuales para la alternancia completa en XAML.

En el ejemplo ToggleLabel se usa ToggleBehavior con DataTrigger para usar Label con dos cadenas de texto para la alternancia.

El ejemplo FormattedTextToggle amplía este concepto cambiando entre dos objetos FormattedString.

La clase ToggleBase de la biblioteca Xamarin.FormsBook.Toolkit se deriva de ContentView, define una propiedad IsToggled e incorpora un elemento ToggleBehavior para la lógica de alternancia. De este modo, resulta más fácil definir el botón de alternancia en XAML, tal como se muestra en el ejemplo TraditionalCheckBox.

SwitchCloneDemo incluye una clase SwitchClone que se deriva de ToggleBase y usa una clase TranslateAction para construir un botón de alternancia similar a Xamarin.FormsSwitch.

RotateAction en Xamarin.FormsBook.Toolkit proporciona una animación que se usa para crear una opción animada en el ejemplo LeverToggle.

Respuesta a pulsaciones

Una desventaja de EventTrigger es que no se puede adjuntar a TapGestureRecognizer para responder a las pulsaciones. Solucionar ese problema es el propósito de TapBehavior en Xamarin.FormsBook.Toolkit.

En el ejemplo BoxViewTapShiver se usa TapBehavior para usar el elemento ShiverAction anterior para los elementos BoxView que se pulsan.

En el ejemplo ShiverViews se muestra cómo se reduce el marcado mediante la encapsulación de una clase ShiverView.

Botones de radio

La biblioteca Xamarin.FormsBook.Toolkittambién tiene una clase RadioBehavior para crear botones de radio agrupados por un nombre de grupo string.

El programa RadioLabels usa cadenas de texto para su botón de radio. En el ejemplo RadioStyle se usa Style para la diferencia de la apariencia entre los botones seleccionados y no seleccionados. En el ejemplo RadioImages se usan imágenes en casillas para sus botones de radio:

Triple screenshot of Radio Images

En el ejemplo TraditionalRadios se dibujan botones de radio tradicionales con un punto dentro de un círculo.

Atenuaciones y orientación

El ejemplo final, MultiColorSliders, permite cambiar entre tres vistas de selección de color diferentes mediante botones de radio. Las tres vistas se intensifican y atenúan con FadeEnableAction en la biblioteca Xamarin.FormsBook.Toolkit.

El programa también responde a los cambios de orientación entre vertical y horizontal con GridOrientationBehavior en la biblioteca Xamarin.FormsBook.Toolkit.