Recherche…


Introduction

Chaque vue Xamarin.Forms est accompagnée d'un rendu pour chaque plate-forme qui crée une instance d'un contrôle natif. Lorsqu'une vue est rendue sur la plate-forme spécifique, la classe ViewRenderer est instanciée.

Le processus pour ce faire est le suivant:

Créez un contrôle personnalisé Xamarin.Forms.

Consommez le contrôle personnalisé de Xamarin.Forms.

Créez le moteur de rendu personnalisé pour le contrôle sur chaque plate-forme.

Implémenter un contrôle CheckBox

Dans cet exemple, nous allons implémenter une case à cocher personnalisée pour Android et iOS.

Création du contrôle personnalisé

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);
        }
    }
}

Nous commencerons par le moteur de rendu personnalisé Android en créant une nouvelle classe ( CheckboxCustomRenderer ) dans la partie Android de notre solution.

Quelques détails importants à noter:

  • Nous devons marquer le haut de notre classe avec l'attribut ExportRenderer pour que le rendu soit enregistré avec Xamarin.Forms . De cette façon, Xamarin.Forms utilisera ce moteur de rendu lorsqu'il Xamarin.Forms de créer notre objet Checkbox sur Android .
  • Nous faisons la plupart de notre travail dans la méthode OnElementChanged , où nous instancions et configurons notre contrôle natif.

Consommer le contrôle personnalisé

<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>

Création du moteur de rendu personnalisé sur chaque plate-forme

Le processus de création de la classe de rendu personnalisé est le suivant:

  1. Créez une sous-classe de la classe ViewRenderer<T1,T2> qui affiche le contrôle personnalisé. Le premier argument de type doit être le contrôle personnalisé utilisé par le moteur de rendu, dans ce cas, CheckBox . Le deuxième argument de type doit être le contrôle natif qui implémentera le contrôle personnalisé.
  2. Remplacez la méthode OnElementChanged qui OnElementChanged le contrôle personnalisé et écrit la logique pour le personnaliser. Cette méthode est appelée lorsque le contrôle Xamarin.Forms correspondant est créé.
  3. Ajoutez un attribut ExportRenderer à la classe de rendu personnalisée pour indiquer qu'elle sera utilisée pour effectuer le rendu du contrôle personnalisé Xamarin.Forms . Cet attribut est utilisé pour enregistrer le moteur de rendu personnalisé avec Xamarin.Forms .

Création du moteur de rendu personnalisé pour 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;
            }
        }
    }
}

Création du moteur de rendu personnalisé pour iOS

Comme dans iOS, la case à cocher n'est pas intégrée, nous allons d'abord créer un CheckBoxView puis créer un moteur de rendu pour notre case à cocher Xamarin.Forms.

Le CheckBoxView est basé sur deux images, checked_checkbox.png et unchecked_checkbox.png, afin que la propriété Color soit ignorée.

La vue 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);
        }
    }
}

Le moteur de rendu personnalisé 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;
            }
        }
    }
}

Résultat:

entrer la description de l'image ici entrer la description de l'image ici



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow