Custom DatePicker and TimePicker (combined) Recipe

Hi guys, I just wanted to share a custom render for an extended DatePicker. This way, users will be able to select Date and Time in a single control. You can also select the time interval, in my case I needed 15 minutes intervals. It took me a while to sort it out, so hopefully it will save you some time.

This is only for iOS, but will post Droid when I get there. Xamarin team should include this control in future versions.

Note: DatePicker will only show the date, with no time. You need to display the value in a separate Label.

Xamarin Forms:

public class CustomDateTimePicker : DatePicker
    {
        private DateTime cdt;
        public event EventHandler<DateTimePickerArgs> DTChanged;
        public DateTime CDT
        {
            get { return cdt; }
            set
            {
                cdt = this.Date = value;
                if (DTChanged != null)
                    DTChanged.Invoke(this, new DateTimePickerArgs(cdt));
            }
        }
    }

    public class DateTimePickerArgs : EventArgs
    {
        private DateTime dt;
        public DateTimePickerArgs(DateTime NewDT)
        {
            dt = NewDT;
        }
        public DateTime DT { get { return dt; } }
    }

Xamarin iOS Custom Render

                    [assembly: ExportRenderer(typeof(CustomDateTimePicker), typeof(CustomDateTimePickerRenderer))]

                    namespace ProjectX.iOS.CustomRenderers
                    {
                        public class CustomDateTimePickerRenderer : DatePickerRenderer
                        {
                            public CustomDateTimePicker dtPicker;
                            protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
                            {
                                base.OnElementChanged(e);

                                dtPicker = e.NewElement as CustomDateTimePicker;

                                if (Control!=null)
                                {
                                    var input = Control.InputView as UIDatePicker;
                                    if (input != null && input.Mode != UIDatePickerMode.DateAndTime)
                                    {
                                        input.Mode = UIDatePickerMode.DateAndTime;
                                        input.MinuteInterval = 15;//TODO CHECK
                                        input.ValueChanged += Input_ValueChanged;
                                    }
                                }
                            }
                            private void Input_ValueChanged(object sender, EventArgs e)
                            {
                                if (Control != null)
                                {
                                    var input = sender as UIDatePicker;

                                    if (dtPicker != null)
                                    {
                                        dtPicker.CDT = input.Date.ToDateTime();
                                    }

                                }

                            }
                        }
                    }

Usage
XAML

          <extended:CustomDateTimePicker x:Name="pckDate" 
                  Grid.Row="0" Grid.RowSpan="2" 
                  BackgroundColor="Transparent" 
                  TextColor="Black" IsVisible="False"
                  HorizontalOptions="Center"
                  VerticalOptions="Center"
                  Format="dddd, dd MMMM hh:mm tt"
                  />

Event wireup
pckDate.DTChanged += PckDate_DTChanged;

To make it visible (since its always invisible)

        private void Schedule_Tapped(object sender, EventArgs e)
        {
            Device.BeginInvokeOnMainThread(() =>
            {
                pckDate.Focus();
            });
        }

Extras (In AppDelegate):
UIDatePicker.Appearance.BackgroundColor = bgColor;
UIDatePicker.Appearance.TintColor = textColor;

Posts

  • pmdpmd USMember ✭✭

    @VictorArce.8951 said:
    Hi guys, I just wanted to share a custom render for an extended DatePicker. This way, users will be able to select Date and Time in a single control. You can also select the time interval, in my case I needed 15 minutes intervals. It took me a while to sort it out, so hopefully it will save you some time.

    This is only for iOS, but will post Droid when I get there. Xamarin team should include this control in future versions.

    Note: DatePicker will only show the date, with no time. You need to display the value in a separate Label.

    Xamarin Forms:

    public class CustomDateTimePicker : DatePicker
        {
            private DateTime cdt;
            public event EventHandler<DateTimePickerArgs> DTChanged;
            public DateTime CDT
            {
                get { return cdt; }
                set
                {
                    cdt = this.Date = value;
                    if (DTChanged != null)
                        DTChanged.Invoke(this, new DateTimePickerArgs(cdt));
                }
            }
        }
    
        public class DateTimePickerArgs : EventArgs
        {
            private DateTime dt;
            public DateTimePickerArgs(DateTime NewDT)
            {
                dt = NewDT;
            }
            public DateTime DT { get { return dt; } }
        }
    

    Xamarin iOS Custom Render

                        [assembly: ExportRenderer(typeof(CustomDateTimePicker), typeof(CustomDateTimePickerRenderer))]
                        
                        namespace ProjectX.iOS.CustomRenderers
                        {
                            public class CustomDateTimePickerRenderer : DatePickerRenderer
                            {
                                public CustomDateTimePicker dtPicker;
                                protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
                                {
                                    base.OnElementChanged(e);
                        
                                    dtPicker = e.NewElement as CustomDateTimePicker;
                        
                                    if (Control!=null)
                                    {
                                        var input = Control.InputView as UIDatePicker;
                                        if (input != null && input.Mode != UIDatePickerMode.DateAndTime)
                                        {
                                            input.Mode = UIDatePickerMode.DateAndTime;
                                            input.MinuteInterval = 15;//TODO CHECK
                                            input.ValueChanged += Input_ValueChanged;
                                        }
                                    }
                                }
                                private void Input_ValueChanged(object sender, EventArgs e)
                                {
                                    if (Control != null)
                                    {
                                        var input = sender as UIDatePicker;
                        
                                        if (dtPicker != null)
                                        {
                                            dtPicker.CDT = input.Date.ToDateTime();
                                        }
                        
                                    }
                        
                                }
                            }
                        }
    

    Usage
    XAML

              <extended:CustomDateTimePicker x:Name="pckDate" 
                      Grid.Row="0" Grid.RowSpan="2" 
                      BackgroundColor="Transparent" 
                      TextColor="Black" IsVisible="False"
                      HorizontalOptions="Center"
                      VerticalOptions="Center"
                      Format="dddd, dd MMMM hh:mm tt"
                      />
    

    Event wireup
    pckDate.DTChanged += PckDate_DTChanged;

    To make it visible (since its always invisible)

            private void Schedule_Tapped(object sender, EventArgs e)
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    pckDate.Focus();
                });
            }
    

    Extras (In AppDelegate):
    UIDatePicker.Appearance.BackgroundColor = bgColor;
    UIDatePicker.Appearance.TintColor = textColor;

    any scope for Droid version?

  • MichaelCyferMichaelCyfer Member ✭✭

    Any update on the progress of a version for Android, and stretching it by asking for UWP as well?
    I've been trying my hand at my own versions but can't seem to get it right.

  • AditkothariAditkothari USMember ✭✭

    Any update on android ?

Sign In or Register to comment.