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.Forms utilizzerà questo renderer quando sta tentando di creare il nostro oggetto Checkbox su Android .
  • 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:

  1. 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 caso CheckBox . Il secondo argomento di tipo dovrebbe essere il controllo nativo che implementerà il controllo personalizzato.
  2. Sovrascrivi il metodo OnElementChanged che OnElementChanged rendering del controllo personalizzato e della logica di scrittura per personalizzarlo. Questo metodo viene chiamato quando viene creato il controllo Xamarin.Forms corrispondente.
  3. Aggiungi un attributo ExportRenderer alla classe di rendering personalizzata per specificare che verrà utilizzato per il rendering del controllo personalizzato Xamarin.Forms . Questo attributo viene utilizzato per registrare il renderizzatore personalizzato con Xamarin.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:

inserisci la descrizione dell'immagine qui inserisci la descrizione dell'immagine qui



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow