Xamarin.Forms                
            Creazione di controlli personalizzati
        
        
            
    Ricerca…
introduzione
 Ogni vista Xamarin.Forms ha un renderer di accompagnamento per ogni piattaforma che crea un'istanza di un controllo nativo. Quando una vista viene renderizzata sulla piattaforma specifica, la classe ViewRenderer viene istanziata. 
Il processo per farlo è il seguente:
Creare un controllo personalizzato Xamarin.Forms.
Consuma il controllo personalizzato da Xamarin.Forms.
Creare il renderizzatore personalizzato per il controllo su ciascuna piattaforma.
Implementazione di un controllo CheckBox
In questo esempio implementeremo una casella di controllo personalizzata per Android e iOS.
Creazione del controllo personalizzato
namespace CheckBoxCustomRendererExample
{
    public class Checkbox : View
    {
        public static readonly BindableProperty IsCheckedProperty = BindableProperty.Create<Checkbox, bool>(p => p.IsChecked, true, propertyChanged: (s, o, n) => { (s as Checkbox).OnChecked(new EventArgs()); });
        public static readonly BindableProperty ColorProperty = BindableProperty.Create<Checkbox, Color>(p => p.Color, Color.Default);
        public bool IsChecked
        {
            get
            {
                return (bool)GetValue(IsCheckedProperty);
            }
            set
            {
                SetValue(IsCheckedProperty, value);
            }
        }
        public Color Color
        {
            get
            {
                return (Color)GetValue(ColorProperty);
            }
            set
            {
                SetValue(ColorProperty, value);
            }
        }
        public event EventHandler Checked;
        protected virtual void OnChecked(EventArgs e)
        {
            if (Checked != null)
                Checked(this, e);
        }
    }
}
 Iniziamo con il rendering personalizzato di Android creando una nuova classe ( CheckboxCustomRenderer ) nella parte Android della nostra soluzione. 
Alcuni dettagli importanti da notare:
-  Dobbiamo contrassegnare la parte superiore della nostra classe con l'attributo ExportRenderer in modo che il renderer sia registrato con Xamarin.Forms. In questo modo,Xamarin.Formsutilizzerà questo renderer quando sta tentando di creare il nostro oggettoCheckboxsuAndroid.
-  Stiamo facendo la maggior parte del nostro lavoro nel metodo OnElementChanged, dove istanziamo e impostiamo il nostro controllo nativo.
Consumare il controllo personalizzato
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:CheckBoxCustomRendererExample" x:Class="CheckBoxCustomRendererExample.CheckBoxCustomRendererExamplePage">
    <StackLayout Padding="20">
        <local:Checkbox Color="Aqua" />
    </StackLayout>
</ContentPage>
Creazione del renderizzatore personalizzato su ciascuna piattaforma
La procedura per la creazione della classe di rendering personalizzata è la seguente:
-  Creare una sottoclasse della classe ViewRenderer<T1,T2>che esegue il rendering del controllo personalizzato. Il primo argomento di tipo dovrebbe essere il controllo personalizzato per il renderer, in questo casoCheckBox. Il secondo argomento di tipo dovrebbe essere il controllo nativo che implementerà il controllo personalizzato.
-  Sovrascrivi il metodo OnElementChangedcheOnElementChangedrendering del controllo personalizzato e della logica di scrittura per personalizzarlo. Questo metodo viene chiamato quando viene creato il controlloXamarin.Formscorrispondente.
-  Aggiungi un attributo ExportRendereralla classe di rendering personalizzata per specificare che verrà utilizzato per il rendering del controllo personalizzatoXamarin.Forms. Questo attributo viene utilizzato per registrare il renderizzatore personalizzato conXamarin.Forms.
Creazione del renderizzatore personalizzato per Android
[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.Droid
{
    public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBox>
    {
        private CheckBox checkBox;
        protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
        {
            base.OnElementChanged(e);
            var model = e.NewElement;
            checkBox = new CheckBox(Context);
            checkBox.Tag = this;
            CheckboxPropertyChanged(model, null);
            checkBox.SetOnClickListener(new ClickListener(model));
            SetNativeControl(checkBox);
        }
        private void CheckboxPropertyChanged(Checkbox model, String propertyName)
        {
            if (propertyName == null || Checkbox.IsCheckedProperty.PropertyName == propertyName)
            {
                checkBox.Checked = model.IsChecked;
            }
            if (propertyName == null || Checkbox.ColorProperty.PropertyName == propertyName)
            {
                int[][] states = {
                    new int[] { Android.Resource.Attribute.StateEnabled}, // enabled
                    new int[] {Android.Resource.Attribute.StateEnabled}, // disabled
                    new int[] {Android.Resource.Attribute.StateChecked}, // unchecked
                    new int[] { Android.Resource.Attribute.StatePressed}  // pressed
                };
                var checkBoxColor = (int)model.Color.ToAndroid();
                int[] colors = {
                    checkBoxColor,
                    checkBoxColor,
                    checkBoxColor,
                    checkBoxColor
                };
                var myList = new Android.Content.Res.ColorStateList(states, colors);
                checkBox.ButtonTintList = myList;
            }
        }
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (checkBox != null)
            {
                base.OnElementPropertyChanged(sender, e);
                CheckboxPropertyChanged((Checkbox)sender, e.PropertyName);
            }
        }
        public class ClickListener : Java.Lang.Object, IOnClickListener
        {
            private Checkbox _myCheckbox;
            public ClickListener(Checkbox myCheckbox)
            {
                this._myCheckbox = myCheckbox;
            }
            public void OnClick(global::Android.Views.View v)
            {
                _myCheckbox.IsChecked = !_myCheckbox.IsChecked;
            }
        }
    }
}
Creazione del renderizzatore personalizzato per iOS
 Poiché in iOS la casella di controllo non è integrata, creeremo prima un CheckBoxView e poi creeremo un renderer per la nostra casella di controllo Xamarin.Forms. 
 CheckBoxView è basato su due immagini: checked_checkbox.png e unchecked_checkbox.png, quindi la proprietà Color verrà ignorata. 
La vista CheckBox:
namespace CheckBoxCustomRendererExample.iOS
{        
    [Register("CheckBoxView")]
    public class CheckBoxView : UIButton
    {
        public CheckBoxView()
        {
            Initialize();
        }
        public CheckBoxView(CGRect bounds)
            : base(bounds)
        {
            Initialize();
        }
        public string CheckedTitle
        {
            set
            {
                SetTitle(value, UIControlState.Selected);
            }
        }
        public string UncheckedTitle
        {
            set
            {
                SetTitle(value, UIControlState.Normal);
            }
        }
        public bool Checked
        {
            set { Selected = value; }
            get { return Selected; }
        }
        void Initialize()
        {
            ApplyStyle();
            TouchUpInside += (sender, args) => Selected = !Selected;
            // set default color, because type is not UIButtonType.System 
            SetTitleColor(UIColor.DarkTextColor, UIControlState.Normal);
            SetTitleColor(UIColor.DarkTextColor, UIControlState.Selected);
        }
        void ApplyStyle()
        {
            SetImage(UIImage.FromBundle("Images/checked_checkbox.png"), UIControlState.Selected);
            SetImage(UIImage.FromBundle("Images/unchecked_checkbox.png"), UIControlState.Normal);
        }
    }
}
Il renderer personalizzato CheckBox:
[assembly: ExportRenderer(typeof(Checkbox), typeof(CheckBoxRenderer))]
namespace CheckBoxCustomRendererExample.iOS
{
    public class CheckBoxRenderer : ViewRenderer<Checkbox, CheckBoxView>
    {
        /// <summary>
        /// Handles the Element Changed event
        /// </summary>
        /// <param name="e">The e.</param>
        protected override void OnElementChanged(ElementChangedEventArgs<Checkbox> e)
        {
            base.OnElementChanged(e);
            if (Element == null)
                return;
            BackgroundColor = Element.BackgroundColor.ToUIColor();
            if (e.NewElement != null)
            {
                if (Control == null)
                {
                    var checkBox = new CheckBoxView(Bounds);
                    checkBox.TouchUpInside += (s, args) => Element.IsChecked = Control.Checked;
                    SetNativeControl(checkBox);
                }
                Control.Checked = e.NewElement.IsChecked;
            }
            Control.Frame = Frame;
            Control.Bounds = Bounds;
        }
        /// <summary>
        /// Handles the <see cref="E:ElementPropertyChanged" /> event.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            base.OnElementPropertyChanged(sender, e);
            if (e.PropertyName.Equals("Checked"))
            {
                Control.Checked = Element.IsChecked;
            }
        }
    }
}
Risultato:

