Share via


Creación de un representador de objeto visual Xamarin.Forms

El objeto visual Xamarin.Forms permite crear representadores y aplicarlos selectivamente a objetos VisualElement, sin tener que crear subclases de vistas Xamarin.Forms. Un representador que especifica un tipo IVisual, como parte de su ExportRendererAttribute, se usará para representar vistas opcionales, en lugar del representador predeterminado. En el momento de la selección del representador, se inspecciona la propiedad Visual de la vista y se incluye en el proceso de selección del representador.

Importante

Actualmente, la propiedad Visual no se puede cambiar después de representar la vista, pero esto cambiará en una versión futura.

El proceso para crear y consumir un representador de objeto visual Xamarin.Forms es el siguiente:

  1. Cree representadores de plataforma para la vista necesaria. Para más información, vea Creación de representadores.
  2. Crea un tipo derivado de IVisual. Para más información, vea Creación de un tipo IVisual.
  3. Registre el tipo IVisual como parte de la instancia de ExportRendererAttribute que decora los representadores. Para más información, vea Registro del tipo IVisual.
  4. Para usar el representador de objeto visual, establezca la propiedad Visual de la vista en el nombre IVisual. Para más información, vea Descarga del representador de objeto visual.
  5. [opcional] Registre un nombre para el tipo IVisual. Para más información, vea Registro de un nombre para el tipo IVisual.

Creación de representadores de plataforma

Para obtener información sobre cómo crear una clase de representador, vea Representadores personalizados. Pero tenga en cuenta que un representador de objeto visual Xamarin.Forms se aplica a una vista sin tener que crear una subclase de la vista.

Las clases de representador que se describen aquí implementan una instancia personalizada de Button que muestra su texto con una sombra.

iOS

En el siguiente ejemplo de código se muestra el representador de botón para iOS:

public class CustomButtonRenderer : ButtonRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Cleanup
        }

        if (e.NewElement != null)
        {
            Control.TitleShadowOffset = new CoreGraphics.CGSize(1, 1);
            Control.SetTitleShadowColor(Color.Black.ToUIColor(), UIKit.UIControlState.Normal);
        }
    }
}

Android

En el siguiente ejemplo de código se muestra el representador de botón para Android:

public class CustomButtonRenderer : Xamarin.Forms.Platform.Android.AppCompat.ButtonRenderer
{
    public CustomButtonRenderer(Context context) : base(context)
    {
    }

    protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
    {
        base.OnElementChanged(e);

        if (e.OldElement != null)
        {
            // Cleanup
        }

        if (e.NewElement != null)
        {
            Control.SetShadowLayer(5, 3, 3, Color.Black.ToAndroid());
        }
    }
}

Creación de un tipo IVisual

En la biblioteca multiplataforma, cree un tipo derivado de IVisual:

public class CustomVisual : IVisual
{
}

Después, el tipo CustomVisual se puede registrar en las clases del representador, lo que permite optar por recibir objetos Button mediante los representadores.

Registro del tipo IVisual

En los proyectos de plataforma, agregue ExportRendererAttribute en el nivel de ensamblado:

[assembly: ExportRenderer(typeof(Xamarin.Forms.Button), typeof(CustomButtonRenderer), new[] { typeof(CustomVisual) })]
namespace VisualDemos.iOS
{
    public class CustomButtonRenderer : ButtonRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Button> e)
        {
            // ...
        }
    }
}

En este ejemplo para el proyecto de plataforma iOS, ExportRendererAttribute especifica que la clase CustomButtonRenderer se usará para representar objetos Button consumidos, con el tipo IVisual registrado como tercer argumento. Un representador que especifica un tipo IVisual, como parte de su ExportRendererAttribute, se usará para representar vistas opcionales, en lugar del representador predeterminado.

Consumo del representador de objeto visual

Se puede optar por recibir un objeto Button mediante las clases de representador si se establece su propiedad Visual en Custom:

<Button Visual="Custom"
        Text="CUSTOM BUTTON"
        BackgroundColor="{StaticResource PrimaryColor}"
        TextColor="{StaticResource SecondaryTextColor}"
        HorizontalOptions="FillAndExpand" />

Nota:

En XAML, un convertidor de tipos quita la necesidad de incluir el sufijo "Visual" en el valor de la propiedad Visual. Pero también se puede especificar el nombre de tipo completo.

El código de C# equivalente es el siguiente:

Button button = new Button { Text = "CUSTOM BUTTON", ... };
button.Visual = new CustomVisual();

En el momento de la selección del representador, se inspecciona la propiedad Visual de Button y se incluye en el proceso de selección del representador. Si no se encuentra un representador, se usará el representador predeterminado Xamarin.Forms.

En las capturas de pantalla siguientes se muestra la instancia representada de Button, que muestra su texto con una sombra:

Captura de pantalla del botón personalizado con texto sombreado, en iOS y Android

Registro de un nombre para el tipo IVisual

VisualAttribute se puede usar para registrar opcionalmente otro nombre para el tipo IVisual. Este enfoque se puede usar para resolver conflictos de nomenclatura entre diferentes bibliotecas de objetos visuales o en situaciones en las que solo se quiere hacer referencia a un objeto visual con un nombre diferente al de su tipo.

VisualAttribute se debe definir en el nivel de ensamblado en la biblioteca multiplataforma o en el proyecto de plataforma:

[assembly: Visual("MyVisual", typeof(CustomVisual))]

Después, el tipo IVisual se puede consumir mediante su nombre registrado:

<Button Visual="MyVisual"
        ... />

Nota:

Al consumir un objeto visual a mediante su nombre registrado, se debe incluir cualquier sufijo "Visual".