Personalización de una entradaCustomizing an Entry

Descargar ejemplo Descargar el ejemploDownload Sample Download the sample

El control Entry de :::no-loc(Xamarin.Forms)::: permite que se edite una sola línea de texto. En este artículo se muestra cómo crear un representador personalizado para el control Entry, lo que permite que los desarrolladores reemplacen la representación nativa de forma predeterminada con su propia personalización específica de la plataforma.The :::no-loc(Xamarin.Forms)::: Entry control allows a single line of text to be edited. This article demonstrates how to create a custom renderer for the Entry control, enabling developers to override the default native rendering with their own platform-specific customization.

Todos los controles de :::no-loc(Xamarin.Forms)::: tienen un representador que las acompaña para cada plataforma y que crea una instancia de un control nativo.Every :::no-loc(Xamarin.Forms)::: control has an accompanying renderer for each platform that creates an instance of a native control. Cuando una aplicación de :::no-loc(Xamarin.Forms)::: representa un control Entry, se crea en iOS una instancia de la clase EntryRenderer que, a su vez, crea una instancia de un control UITextField nativo.When an Entry control is rendered by a :::no-loc(Xamarin.Forms)::: application, in iOS the EntryRenderer class is instantiated, which in turns instantiates a native UITextField control. En la plataforma Android, la clase EntryRenderer crea una instancia de un control EditText.On the Android platform, the EntryRenderer class instantiates an EditText control. En la Plataforma universal de Windows (UWP), la clase EntryRenderer crea una instancia de un control TextBox.On the Universal Windows Platform (UWP), the EntryRenderer class instantiates a TextBox control. Para obtener más información sobre el representador y las clases de control nativo a las que se asignan los controles de :::no-loc(Xamarin.Forms):::, vea Clases base y controles nativos del representador.For more information about the renderer and native control classes that :::no-loc(Xamarin.Forms)::: controls map to, see Renderer Base Classes and Native Controls.

El siguiente diagrama muestra la relación entre el control Entry y los controles nativos correspondientes que lo implementan:The following diagram illustrates the relationship between the Entry control and the corresponding native controls that implement it:

Relación entre el control Entry y los controles nativos de implementación

El proceso de representación puede aprovecharse para implementar las personalizaciones específicas de la plataforma creando un representador personalizado para el control Entry en cada plataforma.The rendering process can be taken advantage of to implement platform-specific customizations by creating a custom renderer for the Entry control on each platform. Para hacerlo, siga este procedimiento:The process for doing this is as follows:

  1. Cree un control personalizado de :::no-loc(Xamarin.Forms):::.Create a :::no-loc(Xamarin.Forms)::: custom control.
  2. Consuma el control personalizado de :::no-loc(Xamarin.Forms):::.Consume the custom control from :::no-loc(Xamarin.Forms):::.
  3. Cree el representador personalizado para el control en cada plataforma.Create the custom renderer for the control on each platform.

Ahora se analizará en detalle cada elemento, para implementar un control Entry que tiene un color de fondo diferente en cada plataforma.Each item will now be discussed in turn, to implement an Entry control that has a different background color on each platform.

Importante

En este artículo se explica cómo crear un representador personalizado simple.This article explains how to create a simple custom renderer. Empero, no es necesario crear un representador personalizado para implementar un Entry que tiene un color de fondo diferente en cada plataforma.However, it's not necessary to create a custom renderer to implement an Entry that has a different background color on each platform. Esto puede realizarse más fácilmente usando la clase Device o la extensión de marcado OnPlatform, para proporcionar los valores específicos de la plataforma.This can be more easily accomplished by using the Device class, or the OnPlatform markup extension, to provide platform-specific values. Para obtener más información, vea Providing Platform-Specific Values (Proporcionar valores específicos de la plataforma) y OnPlatform Markup Extension (Extensión de marcado OnPlatform).For more information, see Providing Platform-Specific Values and OnPlatform Markup Extension.

Creación de un control Entry personalizadoCreating the Custom Entry Control

Se puede crear un control Entry personalizado mediante la creación de subclases del control Entry, como se muestra en el siguiente ejemplo de código:A custom Entry control can be created by subclassing the Entry control, as shown in the following code example:

public class MyEntry : Entry
{
}

El control MyEntry se crea en el proyecto de biblioteca de .NET Standard y es simplemente un control Entry.The MyEntry control is created in the .NET Standard library project and is simply an Entry control. La personalización del control se llevará a cabo en el representador personalizado, por lo que no se requiere ninguna implementación adicional en el control MyEntry.Customization of the control will be carried out in the custom renderer, so no additional implementation is required in the MyEntry control.

Uso del control personalizadoConsuming the Custom Control

En XAML puede hacerse referencia al control MyEntry en el proyecto de biblioteca de .NET Standard declarando un espacio de nombres para su ubicación y usando el prefijo del espacio de nombres en el elemento de control.The MyEntry control can be referenced in XAML in the .NET Standard library project by declaring a namespace for its location and using the namespace prefix on the control element. El siguiente ejemplo de código muestra cómo el control personalizado MyEntry puede utilizarse en una página XAML:The following code example shows how the MyEntry control can be consumed by a XAML page:

<ContentPage ...
    xmlns:local="clr-namespace:CustomRenderer;assembly=CustomRenderer"
    ...>
    ...
    <local:MyEntry Text="In Shared Code" />
    ...
</ContentPage>

El prefijo de espacio de nombres local puede tener cualquier nombre.The local namespace prefix can be named anything. Pero los valores clr-namespace y assembly deben coincidir con los detalles del control personalizado.However, the clr-namespace and assembly values must match the details of the custom control. Una vez que se declara el espacio de nombres, el prefijo se usa para hacer referencia al control personalizado.Once the namespace is declared the prefix is used to reference the custom control.

El siguiente ejemplo de código muestra cómo el control personalizado MyEntry puede utilizarse en una página C#:The following code example shows how the MyEntry control can be consumed by a C# page:

public class MainPage : ContentPage
{
  public MainPage ()
  {
    Content = new StackLayout {
      Children = {
        new Label {
          Text = "Hello, Custom Renderer !",
        },
        new MyEntry {
          Text = "In Shared Code",
        }
      },
      VerticalOptions = LayoutOptions.CenterAndExpand,
      HorizontalOptions = LayoutOptions.CenterAndExpand,
    };
  }
}

Este código crea una instancia de un nuevo objeto ContentPage que mostrará un Label y un control MyEntry centrado tanto vertical como horizontalmente en la página.This code instantiates a new ContentPage object that will display a Label and MyEntry control centered both vertically and horizontally on the page.

Ahora se puede agregar un representador personalizado a cada proyecto de aplicación para personalizar la apariencia del control en cada plataforma.A custom renderer can now be added to each application project to customize the control's appearance on each platform.

Creación del representador personalizado en cada plataformaCreating the Custom Renderer on each Platform

El proceso para crear la clase del representador personalizado es el siguiente:The process for creating the custom renderer class is as follows:

  1. Cree una subclase de la clase EntryRenderer que representa el control nativo.Create a subclass of the EntryRenderer class that renders the native control.
  2. Invalide el método OnElementChanged que representa el control nativo y escriba lógica para personalizar el control.Override the OnElementChanged method that renders the native control and write logic to customize the control. Se llama a este método cuando se crea el correspondiente control de :::no-loc(Xamarin.Forms):::.This method is called when the corresponding :::no-loc(Xamarin.Forms)::: control is created.
  3. Agregue un atributo ExportRenderer a la clase de representador personalizada para especificar que se usará para representar el control de :::no-loc(Xamarin.Forms):::.Add an ExportRenderer attribute to the custom renderer class to specify that it will be used to render the :::no-loc(Xamarin.Forms)::: control. Este atributo se usa para registrar al representador personalizado con :::no-loc(Xamarin.Forms):::.This attribute is used to register the custom renderer with :::no-loc(Xamarin.Forms):::.

Nota

Proporcionar un representador personalizado en cada proyecto de la plataforma es un paso opcional.It is optional to provide a custom renderer in each platform project. Si no se registra un representador personalizado, se usará el representador predeterminado de la clase base del control.If a custom renderer isn't registered, then the default renderer for the control's base class will be used.

El siguiente diagrama muestra las responsabilidades de cada proyecto de la aplicación de ejemplo, junto con las relaciones entre ellos:The following diagram illustrates the responsibilities of each project in the sample application, along with the relationships between them:

Responsabilidades del proyecto de representador personalizado MyEntry

Las clases MyEntryRenderer del representador específico de la plataforma, que se derivan de la clase EntryRenderer para cada plataforma, representan el control MyEntry.The MyEntry control is rendered by platform-specific MyEntryRenderer classes, which all derive from the EntryRenderer class for each platform. Esto da como resultado que cada control MyEntry se represente con un color de fondo específico de la plataforma, como se muestra en las siguientes capturas de pantalla:This results in each MyEntry control being rendered with a platform-specific background color, as shown in the following screenshots:

Control MyEntry en cada plataforma

La clase EntryRenderer expone el método OnElementChanged, al que se llama cuando se crea el control de :::no-loc(Xamarin.Forms)::: para representar el control nativo correspondiente.The EntryRenderer class exposes the OnElementChanged method, which is called when the :::no-loc(Xamarin.Forms)::: control is created to render the corresponding native control. Este método toma un parámetro ElementChangedEventArgs que contiene propiedades OldElement y NewElement.This method takes an ElementChangedEventArgs parameter that contains OldElement and NewElement properties. Estas propiedades representan al elemento de :::no-loc(Xamarin.Forms)::: al que estaba asociado el representador y al elemento de :::no-loc(Xamarin.Forms)::: al que está asociado el representador, respectivamente.These properties represent the :::no-loc(Xamarin.Forms)::: element that the renderer was attached to, and the :::no-loc(Xamarin.Forms)::: element that the renderer is attached to, respectively. En la aplicación de ejemplo, la propiedad OldElement es null y la propiedad NewElement contiene una referencia al control de MyEntry.In the sample application the OldElement property will be null and the NewElement property will contain a reference to the MyEntry control.

El lugar para realizar la personalización del control nativo es una versión reemplazada del método OnElementChanged en la clase MyEntryRenderer.An overridden version of the OnElementChanged method in the MyEntryRenderer class is the place to perform the native control customization. Una referencia con tipo para el control nativo que se usa en la plataforma puede obtenerse a través de la propiedad Control.A typed reference to the native control being used on the platform can be accessed through the Control property. Además, se puede obtener una referencia al control de :::no-loc(Xamarin.Forms)::: que se representa mediante la propiedad Element, aunque no se usa en la aplicación de ejemplo.In addition, a reference to the :::no-loc(Xamarin.Forms)::: control that's being rendered can be obtained through the Element property, although it's not used in the sample application.

Cada clase de representador personalizado se decora con un atributo ExportRenderer que registra el representador con :::no-loc(Xamarin.Forms):::.Each custom renderer class is decorated with an ExportRenderer attribute that registers the renderer with :::no-loc(Xamarin.Forms):::. El atributo toma dos parámetros: el nombre de tipo del control de :::no-loc(Xamarin.Forms)::: que se representa y el nombre de tipo del representador personalizado.The attribute takes two parameters – the type name of the :::no-loc(Xamarin.Forms)::: control being rendered, and the type name of the custom renderer. El prefijo assembly para el atributo especifica que el atributo se aplica a todo el ensamblado.The assembly prefix to the attribute specifies that the attribute applies to the entire assembly.

En las secciones siguientes se describe la implementación de cada clase de representador personalizado MyEntryRenderer específico de plataforma.The following sections discuss the implementation of each platform-specific MyEntryRenderer custom renderer class.

Creación del representador personalizado en iOSCreating the Custom Renderer on iOS

El siguiente ejemplo de código muestra el representador personalizado para la plataforma iOS:The following code example shows the custom renderer for the iOS platform:

using :::no-loc(Xamarin.Forms):::.Platform.iOS;

[assembly: ExportRenderer (typeof(MyEntry), typeof(MyEntryRenderer))]
namespace CustomRenderer.iOS
{
    public class MyEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged (ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged (e);

            if (Control != null) {
                // do whatever you want to the UITextField here!
                Control.BackgroundColor = UIColor.FromRGB (204, 153, 255);
                Control.BorderStyle = UITextBorderStyle.Line;
            }
        }
    }
}

La llamada al método OnElementChanged de la clase base crea una instancia de un control UITextField de iOS, con una referencia al control que se asigna en la propiedad Control del representador.The call to the base class's OnElementChanged method instantiates an iOS UITextField control, with a reference to the control being assigned to the renderer's Control property. Después se establece el color de fondo en púrpura claro con el método UIColor.FromRGB.The background color is then set to light purple with the UIColor.FromRGB method.

Creación del representador personalizado en AndroidCreating the Custom Renderer on Android

En el ejemplo de código siguiente se muestra el representador personalizado para la plataforma Android:The following code example shows the custom renderer for the Android platform:

using :::no-loc(Xamarin.Forms):::.Platform.Android;

[assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
namespace CustomRenderer.Android
{
    class MyEntryRenderer : EntryRenderer
    {
        public MyEntryRenderer(Context context) : base(context)
        {
        }

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

            if (Control != null)
            {
                Control.SetBackgroundColor(global::Android.Graphics.Color.LightGreen);
            }
        }
    }
}

La llamada al método OnElementChanged de la clase base crea una instancia de un control EditText de Android, con una referencia al control que se asigna en la propiedad Control del representador.The call to the base class's OnElementChanged method instantiates an Android EditText control, with a reference to the control being assigned to the renderer's Control property. Después se establece el color de fondo en verde claro con el método Control.SetBackgroundColor.The background color is then set to light green with the Control.SetBackgroundColor method.

Creación del representador personalizado en UWPCreating the Custom Renderer on UWP

En el siguiente ejemplo de código se muestra el representador personalizado para UWP:The following code example shows the custom renderer for UWP:

[assembly: ExportRenderer(typeof(MyEntry), typeof(MyEntryRenderer))]
namespace CustomRenderer.UWP
{
    public class MyEntryRenderer : EntryRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
        {
            base.OnElementChanged(e);

            if (Control != null)
            {
                Control.Background = new SolidColorBrush(Colors.Cyan);
            }
        }
    }
}

La llamada al método OnElementChanged de la clase base crea una instancia de un control TextBox, con una referencia al control que se asigna en la propiedad Control del representador.The call to the base class's OnElementChanged method instantiates a TextBox control, with a reference to the control being assigned to the renderer's Control property. Después se establece el color de fondo en cian mediante la creación de una instancia de SolidColorBrush.The background color is then set to cyan by creating a SolidColorBrush instance.

ResumenSummary

En este artículo se ha mostrado cómo crear un representador de control personalizado para el control Entry de :::no-loc(Xamarin.Forms):::, lo que permite que los desarrolladores reemplacen la representación nativa predeterminada por su propia representación específica de la plataforma.This article has demonstrated how to create a custom control renderer for the :::no-loc(Xamarin.Forms)::: Entry control, enabling developers to override the default native rendering with their own platform-specific rendering. Los representadores personalizados proporcionan un método eficaz para personalizar la apariencia de los controles de :::no-loc(Xamarin.Forms):::.Custom renderers provide a powerful approach to customizing the appearance of :::no-loc(Xamarin.Forms)::: controls. Se pueden usar para realizar pequeños cambios de estilo o para una personalización sofisticada del diseño y el comportamiento específicos de una plataforma.They can be used for small styling changes or sophisticated platform-specific layout and behavior customization.