Search code examples
formsxamarinxamarin.formsbackgroundpicker

Customize the Xamarin.Forms Picker Popup List


I know how to create a custom renderer to customize the actual text of the Xamarin forms picker, but how do you customize, say, the background color or text of the list that pops up when you click on the picker text box?


Solution

  • You can refer to the following code :

    in iOS

    using System;
    using Xamarin.Forms;
    using xxx;
    using xxx.iOS;
    using UIKit;
    using Xamarin.Forms.Platform.iOS;
    using Foundation;
    
    [assembly:ExportRenderer(typeof(MyPicker), typeof(MyiOSPicker))]
    namespace xxx.iOS
    {
        public class MyiOSPicker:PickerRenderer,IUIPickerViewDelegate
        {
    
          IElementController ElementController => Element as IElementController;
    
          public MyiOSPicker()
          {
    
          }
    
          [Export("pickerView:viewForRow:forComponent:reusingView:")]
          public UIView GetView(UIPickerView pickerView, nint row, nint component, UIView view)
          {
    
             UILabel label = new UILabel
             {
                //here you can set the style of item!!!
    
                TextColor = UIColor.Blue,
    
                Text = Element.Items[(int)row].ToString(),
    
                TextAlignment = UITextAlignment.Center,
    
             };
             return label;
          }
    
    
          protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
          {
            base.OnElementChanged(e);
    
            if(Control!=null)
            {
                UIPickerView pickerView = (UIPickerView)Control.InputView;
                pickerView.WeakDelegate = this;
                pickerView.BackgroundColor = UIColor.Yellow; //set the background color of pickerview
    
            }
    
    
          }
    
    
        }
    }
    

    in Android

    using System;
    using Xamarin.Forms;
    using Xamarin.Forms.Platform.Android;
    using xxx;
    using xxx.Droid;
    using Android.Widget;
    using Android.App;
    using System.Linq;
    
    [assembly: ExportRenderer(typeof(MyPicker), typeof(MyAndroidPicker))]
    namespace xxx.Droid
    {
        public class MyAndroidPicker:PickerRenderer
        {
    
          IElementController ElementController => Element as IElementController;
    
          public MyAndroidPicker()
          {
    
          }
    
    
          private AlertDialog _dialog;
    
          protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
          {
            base.OnElementChanged(e);
    
            if (e.NewElement == null || e.OldElement != null)
                return;
    
            Control.Click += Control_Click;
          }
    
          protected override void Dispose(bool disposing)
          {
            Control.Click -= Control_Click;
            base.Dispose(disposing);
          }
    
          private void Control_Click(object sender, EventArgs e)
          {
            Picker model = Element;
    
            var picker = new NumberPicker(Context);
            if (model.Items != null && model.Items.Any())
            {
                // set style here
                picker.MaxValue = model.Items.Count - 1;
                picker.MinValue = 0;
                picker.SetBackgroundColor(Android.Graphics.Color.Yellow);
                picker.SetDisplayedValues(model.Items.ToArray());
                picker.WrapSelectorWheel = false;
                picker.Value = model.SelectedIndex;
            }
    
            var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
            layout.AddView(picker);
    
            ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, true);
    
            var builder = new AlertDialog.Builder(Context);
            builder.SetView(layout);
    
            builder.SetTitle(model.Title ?? "");
            builder.SetNegativeButton("Cancel  ", (s, a) =>
            {
                ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
                // It is possible for the Content of the Page to be changed when Focus is changed.
                // In this case, we'll lose our Control.
                Control?.ClearFocus();
                _dialog = null;
            });
            builder.SetPositiveButton("Ok ", (s, a) =>
            {
                ElementController.SetValueFromRenderer(Picker.SelectedIndexProperty, picker.Value);
                // It is possible for the Content of the Page to be changed on SelectedIndexChanged.
                // In this case, the Element & Control will no longer exist.
                if (Element != null)
                {
                    if (model.Items.Count > 0 && Element.SelectedIndex >= 0)
                        Control.Text = model.Items[Element.SelectedIndex];
                    ElementController.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
                    // It is also possible for the Content of the Page to be changed when Focus is changed.
                    // In this case, we'll lose our Control.
                    Control?.ClearFocus();
                }
                _dialog = null;
            });
    
            _dialog = builder.Create();
            _dialog.DismissEvent += (ssender, args) =>
            {
                ElementController?.SetValueFromRenderer(VisualElement.IsFocusedProperty, false);
            };
            _dialog.Show();
          }
    
        }
    }