Xamarin forms Picker on android change Cancel text

2019-06-16 09:19发布

Xamarin.Forms on Android. Clicking picker opens dialog and the negative button has default text of "Cancel". How can I change it?

I looked in open source project of Xamarin and they set the positive button text like this

builder.SetNegativeButton(global::Android.Resource.String.Cancel, (s, a) => ...

This method is private so I cant override the class method.

Neither I can copy paste implementation of this class because its members are private to Xamarn dll-s...

Link to that picker implementation on Xamarin.Forms andoid:

https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.Android/Renderers/PickerRenderer.cs

2条回答
乱世女痞
2楼-- · 2019-06-16 09:23

Xamarin forms Picker on android change Cancel text

As an alternative choice, you could rewrite the whole dialog in your PickerRenderer :

public class MyPickerRenderer : Xamarin.Forms.Platform.Android.PickerRenderer
{
    private IElementController ElementController => Element as IElementController;
    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())
        {
            picker.MaxValue = model.Items.Count - 1;
            picker.MinValue = 0;
            picker.SetDisplayedValues(model.Items.ToArray());
            picker.WrapSelectorWheel = false;
            picker.DescendantFocusability = DescendantFocusability.BlockDescendants;
            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 0.0", (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();
    }
}

Effect.

查看更多
相关推荐>>
3楼-- · 2019-06-16 09:48

As the dialog itself is not a graphical element that is directly used in XAML, there is nothing that stops you from using the Android code directly in your project. If you use the shared project it is as simple as using the conditional compiling, if you use standard library then you need to use the dependency service.

On the XAML side you can use a sort of custom EntryRenderer to present the picked item on the screen, that is what Xamarin does with that anyway.

查看更多
登录 后发表回答