Is there any way we can change the cancel button text of Picker? I know that you are supposed to use resx files for localization, but one of the languages I have to support is Kurdish(ckb
) which is not very well supported by most operating systems. So I had to write custom localization logic, but I have trouble localizing some of the system specified strings.
You can change picker's cancel/done button text with custom renderer.
Bindable properties:
public static readonly BindableProperty DoneButtonTextProperty
public static readonly BindableProperty CancelButtonTextProperty
On iOS use DoneButtonProperty in Custom Renderer.
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (e.NewElement == null) return;
var customPicker = e.NewElement as CustomPicker;
if (Control == null)
{
SetNativeControl(new UITextField
{
RightViewMode = UITextFieldViewMode.Always,
ClearButtonMode = UITextFieldViewMode.WhileEditing,
});
SetUIButton(customPicker.DoneButtonText);
}
else
{
SetUIButton(customPicker.DoneButtonText);
}
}
public void SetUIButton(string doneButtonText)
{
UIToolbar toolbar = new UIToolbar();
toolbar.BarStyle = UIBarStyle.Default;
toolbar.Translucent = true;
toolbar.SizeToFit();
UIBarButtonItem doneButton = new UIBarButtonItem(String.IsNullOrEmpty(doneButtonText) ? "Accept" : doneButtonText, UIBarButtonItemStyle.Done, (s, ev) =>
{
Control.ResignFirstResponder();
});
UIBarButtonItem flexible = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);
toolbar.SetItems(new UIBarButtonItem[] { doneButton,flexible }, true);
Control.InputAccessoryView = toolbar;
}
On Android you can use both of the properties.
```
AlertDialog _dialog;
IElementController ElementController => Element as IElementController;
CustomPicker customPicker;
public CustomPickerRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
if (e.NewElement == null) return;
customPicker = e.NewElement as CustomPicker;
if (e.NewElement != null)
{
if (Control == null)
{
var textField = CreateNativeControl();
textField.SetOnClickListener(CustomPickerListener.Instance);
textField.InputType = InputTypes.Null;
SetNativeControl(textField);
}
}
base.OnElementChanged(e);
}
public void OnClick()
{
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 = Android.Views.DescendantFocusability.BlockDescendants;
picker.Value = model.SelectedIndex;
}
var layout = new LinearLayout(Context) { Orientation = Orientation.Vertical };
layout.AddView(picker);
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, true);
var builder = new AlertDialog.Builder(Context);
builder.SetView(layout);
builder.SetTitle(model.Title ?? "");
builder.SetNegativeButton(customPicker.CancelButtonText ?? "Cancel", (s, a) =>
{
ElementController.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
_dialog = null;
});
builder.SetPositiveButton(customPicker.DoneButtonText ?? "Accept", (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.IsFocusedPropertyKey, false);
}
_dialog = null;
});
_dialog = builder.Create();
_dialog.DismissEvent += (sender, args) =>
{
ElementController?.SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
};
_dialog.Show();
}
class CustomPickerListener : Java.Lang.Object, IOnClickListener
{
public static readonly CustomPickerListener Instance = new CustomPickerListener();
public void OnClick(global::Android.Views.View v)
{
var renderer = v.Tag as CustomPickerRenderer;
if (renderer == null)
return;
renderer.OnClick();
}
}
As part of this enhancement, could we also include the ability to set the text color?
Control
How to change UpdateMode from Immediately To WhenFinished
when add this line to xaml iOSSpecific:Picker.UpdateMode="WhenFinished" selected item not updated
@samhouts
Most helpful comment
You can change picker's cancel/done button text with custom renderer.
Bindable properties:
public static readonly BindableProperty DoneButtonTextProperty
public static readonly BindableProperty CancelButtonTextProperty
iOS
On iOS use DoneButtonProperty in Custom Renderer.
Android
On Android you can use both of the properties.
```
AlertDialog _dialog;
IElementController ElementController => Element as IElementController;
CustomPicker customPicker;
public CustomPickerRenderer(Context context) : base(context)
{
}