自定义Xamarin.Forms选择器弹出列表

自定义Xamarin.Forms选择器弹出列表

问题描述:

我知道如何创建自定义渲染器以自定义Xamarin表单选择器的实际文本,但是如何自定义,例如单击选择器文本框时弹出的背景颜色或列表文本?

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?

您可以参考以下代码:

在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

        }


      }


    }
}

在Android中

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

    }
}