Adding a placeholder and aligning text to center on DatePicker

SteveRussellSteveRussell Member ✭✭✭

I'm having trouble with adding a placeholder to my DatePicker (doesn't have title property like a regular picker). I have a custom renderer:

public class DOBPicker : DatePicker { public static readonly BindableProperty EnterTextProperty = BindableProperty.Create(propertyName: "Placeholder", returnType: typeof(string), declaringType: typeof(DOBPicker), defaultValue: default(string)); public string Placeholder { get; set; } }

iOS Renderer:

`protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (this.Control == null)
return;
var element = e.NewElement as DOBPicker;
if (!string.IsNullOrWhiteSpace(element.Placeholder))
{
Control.Text = element.Placeholder;
}

       Control.ShouldEndEditing += (textField) => {
           var seletedDate = (UITextField)textField;
           var text = seletedDate.Text;
           if (text == element.Placeholder)
           {
               Control.Text = DateTime.Now.ToString("dd/MMMM/yyyy");
           }
           return true;
       };
    }
    private void OnCanceled(object sender, EventArgs e)
    {
        Control.ResignFirstResponder();
    }
    private void OnDone(object sender, EventArgs e)
    {
        Control.ResignFirstResponder();
    }`

It works, but when I go back to the previous page, the app crashes and I get an error (Object reference not set to an instance of an object). I think it's referring to

if (!string.IsNullOrWhiteSpace(element.Placeholder)) { Control.Text = element.Placeholder; }

Answers

  • LandLuLandLu Member, Xamarin Team Xamurai

    I tested your renderer on my side, it won't crash when I pop to the previous page. Please specify the steps to help me reproduce your issue:

    Moreover, I think your bindable property's grammar should be corrected:

    public class DOBPicker : DatePicker
    {
        public static readonly BindableProperty PlaceholderProperty = BindableProperty.Create(propertyName: "Placeholder", returnType: typeof(string), declaringType: typeof(DOBPicker), defaultValue: default(string));
        public string Placeholder
        {
            get
            {
                return (string)GetValue(PlaceholderProperty);
            }
            set
            {
                SetValue(PlaceholderProperty, value);
            }
        }
    }
    

    And there's no need to add the ShouldEndEditing event, the code could be optimized like:

    protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
    {
        base.OnElementChanged(e);
    
        if (this.Control == null)
            return;
        var element = e.NewElement as DOBPicker;
        if (!string.IsNullOrWhiteSpace(element.Placeholder))
        {
            Control.Text = element.Placeholder;
        }
    
        //Control.ShouldEndEditing += (textField) => {
        //    var seletedDate = (UITextField)textField;
        //    var text = seletedDate.Text;
        //    if (text == element.Placeholder)
        //    {
        //        Control.Text = DateTime.Now.ToString("dd/MMMM/yyyy");
        //    }
        //    return true;
        //};
    }
    
Sign In or Register to comment.