0

I created a custom DatePicker to look like it has placeholder, but the problem is, when clicking the DatePicker then when the DatePicker Dialog opens and I click on okay with the preselected/default date value of today, The date is not written in the field. Below is my code.

I think the reason is that since "Date" property has a default value of today and there is no change in the selection when the "OK" button was clicked

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    using Xamarin.Forms;
    using Xamarin.Forms.Xaml;
    
    namespace XXX.XXX.Mobile.Controls
    {
        [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class DatePickerWithPlaceHolder : DatePicker
        {
            public static readonly BindableProperty NullableDateProperty = BindableProperty.Create(nameof(NullableDate),typeof(DateTime?),typeof(DatePickerWithPlaceHolder), null, BindingMode.TwoWay);

        private string _format;

        public DateTime? NullableDate
        {
            get => (DateTime?)GetValue(NullableDateProperty);
            set
            {
                SetValue(NullableDateProperty, value);
                UpdateDate();
            }
        }

        private void UpdateDate()
        {
            DatePickerWithPlaceHolder datePicker = this;

            if (NullableDate.HasValue)
            {
                if (null != _format) Format = _format;
                Date = NullableDate.Value;
                datePicker.FontAttributes = FontAttributes.None;
                datePicker.TextColor = Color.Black;
            }
            else
            {
                _format = Format;
                Format = "Select Date";
                datePicker.FontAttributes = FontAttributes.Italic;
                datePicker.TextColor = Color.Gray;
            }
        }

        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            UpdateDate();
        }

        protected override void OnPropertyChanged(string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
            if (propertyName == "Date") NullableDate = Date;
            if (propertyName == "NullableDate") UpdateDate();
        }
    }
}
Endeavor
  • 35
  • 4

1 Answers1

0

I think you need set NullableDate to null in the background code.

Below is the sample code for your reference:

DatePickerWithPlaceHolder.cs

  public class DatePickerWithPlaceHolder : DatePicker
    {
        private string _format = null;
        public static readonly BindableProperty NullableDateProperty = BindableProperty.Create<DatePickerWithPlaceHolder, DateTime?>(p => p.NullableDate, null, BindingMode.TwoWay);
        public DateTime? NullableDate
        {
            get { return (DateTime?)GetValue(NullableDateProperty); }
            set { SetValue(NullableDateProperty, value); UpdateDate(); }
        }
        private void UpdateDate()
        {
            if (NullableDate.HasValue) { if (null != _format) Format = _format; Date = NullableDate.Value; }
            else { _format = Format; Format = "Select Date ..."; FontAttributes = FontAttributes.Italic;
                TextColor = Color.Green;
            }
        }
        protected override void OnBindingContextChanged()
        {
            base.OnBindingContextChanged();
            UpdateDate();
        }
        protected override void OnPropertyChanged(string propertyName = null)
        {
            base.OnPropertyChanged(propertyName);
            if (propertyName == "Date") NullableDate = Date;
        }
    }

Consume it in Xaml:

<appentrymask:DatePickerWithPlaceHolder x:Name="myDatePicker"/>

Initialize the NullableDate in code behind:

    public MainPage()
        {
            InitializeComponent();
            myDatePicker.NullableDate = null;
        }

Last but not least,for detecting the OK or Cancel event, you could refer to this thread.

Alexandar May - MSFT
  • 6,536
  • 1
  • 8
  • 15