

Clearable Time Picker in Xamarin Forms
source link: https://xamgirl.com/clearable-time-picker-in-xamarin-forms/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Clearable Time Picker in Xamarin Forms
A time ago I did an article on how to create a Clearable Date Picker, recently someone asked me to do the same but with a Time Picker. So why not?
In this article, I’m going to show you how to create a Time Picker that can be cleared and set to a null date.
Let’s start
1. In your XF Project create a NullableTimePicker class that extends from TimePicker
This class will have two main bindable properties:
- NullableTime: To bind our nullable TimeSpan.
- PlaceHolder: The value that will be visible when the picker is null, by default it will be “/ . /”.
The code inside is quite simple, a method to clear the NullableTime property and another method to update the time format depending on whether the value is null or not.
public class NullableTimePicker : TimePicker { public NullableTimePicker() { Format = _originalFormat = "hh:mm tt"; }
public static readonly BindableProperty PlaceHolderProperty = BindableProperty.Create(nameof(PlaceHolder), typeof(string), typeof(NullableTimePicker), "/ . /"); public static readonly BindableProperty NullableTimeProperty = BindableProperty.Create(nameof(NullableTime), typeof(TimeSpan?), typeof(NullableTimePicker), null, defaultBindingMode: BindingMode.TwoWay);
public string PlaceHolder { get => (string)GetValue(PlaceHolderProperty); set => SetValue(PlaceHolderProperty, value); }
public TimeSpan? NullableTime { get => (TimeSpan?)GetValue(NullableTimeProperty); set { SetValue(NullableTimeProperty, value); UpdateTimeFormat(); } }
public string _originalFormat { get; private set; } = null;
public void ClearTime() { NullableTime = null; UpdateTimeFormat(); }
protected override void OnBindingContextChanged() { base.OnBindingContextChanged(); if (BindingContext != null) { _originalFormat = Format; UpdateTimeFormat(); } }
protected override void OnPropertyChanged(string propertyName = null) { base.OnPropertyChanged(propertyName);
if (propertyName == TimeProperty.PropertyName || (propertyName == IsFocusedProperty.PropertyName && !IsFocused)) { NullableTime = Time; UpdateTimeFormat(); } }
private void UpdateTimeFormat() { if (NullableTime != null) { Format = _originalFormat; } else { Format = PlaceHolder; } } }
2. In your iOS project create a NullableTimePickerRenderer
Use this renderer to add a Clear button to the iOS TimePicker.
[assembly: ExportRenderer(typeof(NullableTimePicker.Controls.NullableTimePicker), typeof(NullableTimePickerRenderer))] namespace NullableTimePicker.iOS { public class NullableTimePickerRenderer : TimePickerRenderer { protected override void OnElementChanged(ElementChangedEventArgs<TimePicker> e) { base.OnElementChanged(e);
if (e.NewElement != null && this.Control != null) { AddClearButton(); } }
private void AddClearButton() { var originalToolbar = this.Control.InputAccessoryView as UIToolbar;
if (originalToolbar != null && originalToolbar.Items.Length <= 2) { var clearButton = new UIBarButtonItem("Clear", UIBarButtonItemStyle.Plain, ((sender, ev) => { Element.Unfocus(); Element.Time = TimeSpan.Zero; (this.Element as NullableTimePicker.Controls.NullableTimePicker).ClearTime(); }));
var newItems = new List<UIBarButtonItem>(); foreach (var item in originalToolbar.Items) { newItems.Add(item); }
newItems.Insert(0, clearButton);
originalToolbar.Items = newItems.ToArray(); } } } }
3. In your Android project create a NullableTimePickerRenderer
Use this renderer to create a TimePicker view that contains a Clear button.
[assembly: ExportRenderer(typeof(NullableTimePicker.Controls.NullableTimePicker), typeof(NullableTimePickerRenderer))] namespace NullableTimePicker.Droid { public class NullableTimePickerRenderer : ViewRenderer<Controls.NullableTimePicker, EditText> { TimePickerDialog _dialog;
public NullableTimePickerRenderer(Context context) : base(context){ }
protected override void OnElementChanged(ElementChangedEventArgs<Controls.NullableTimePicker> e) { base.OnElementChanged(e);
SetNativeControl(new Android.Widget.EditText(Context));
if (Control == null || e.NewElement == null) return; Control.Click += OnPickerClick; Control.KeyListener = null; Control.FocusChange += OnPickerFocusChange; Control.Enabled = Element.IsEnabled; Control.Text = !Element.NullableTime.HasValue ? Element.PlaceHolder : DateTime.Today.Add(Element.NullableTime.Value).ToString(Element.Format); }
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == Xamarin.Forms.TimePicker.TimeProperty.PropertyName || e.PropertyName == Xamarin.Forms.TimePicker.FormatProperty.PropertyName) { if (Element.Format == Element.PlaceHolder) { this.Control.Text = Element.PlaceHolder; return; } } if (e.PropertyName == NullableTimePicker.Controls.NullableTimePicker.NullableTimeProperty.PropertyName && Control != null && Element != null) { Control.Text = !Element.NullableTime.HasValue ? Element.PlaceHolder : DateTime.Today.Add(Element.NullableTime.Value).ToString(Element.Format); }
base.OnElementPropertyChanged(sender, e); }
void OnPickerFocusChange(object sender, Android.Views.View.FocusChangeEventArgs e) { if (e.HasFocus) { ShowTimePicker(); } }
protected override void Dispose(bool disposing) { if (Control != null) { Control.Click -= OnPickerClick; Control.FocusChange -= OnPickerFocusChange;
if (_dialog != null) { _dialog.Hide(); _dialog.Dispose(); _dialog = null; } }
base.Dispose(disposing); }
void OnPickerClick(object sender, EventArgs e) { ShowTimePicker(); }
void ShowTimePicker() { CreateTimePickerDialog(Element.NullableTime.HasValue? Element.NullableTime.Value.Hours : 0, Element.NullableTime.HasValue ? Element.NullableTime.Value.Minutes : 0, false); _dialog.Show(); }
void CreateTimePickerDialog(int hours, int minutes, bool is24HourView) { _dialog = new TimePickerDialog(Context, (o, e) => { SetTime(new TimeSpan(e.HourOfDay, e.Minute, 0)); ((IElementController)Element).SetValueFromRenderer(VisualElement.IsFocusedProperty, false); Control.ClearFocus();
_dialog = null; }, hours, minutes, is24HourView);
_dialog.SetButton2("Clear", (sender, e) => { this.Element.ClearTime(); Control.Text = this.Element.Format; }); }
void SetTime(TimeSpan time) { Element.Format = this.Element._originalFormat; Control.Text = DateTime.Today.Add(time).ToString(Element.Format); Element.Time = time; } } }
4. Use the control
To use it just add the control in your view and instead of binding the ViewModel property to the Time property, bind it to the NullableTime property instead.
public TimeSpan? MyTime { get; set; }
<?xml version="1.0" encoding="utf-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="NullableTimePicker.MainPage" xmlns:local="clr-namespace:NullableTimePicker.Controls"> <StackLayout VerticalOptions="CenterAndExpand"> <local:NullableTimePicker NullableTime="{Binding MyTime}"/> </StackLayout> </ContentPage>
Result
You can check the full sample source code here.
Happy coding!
Like this:
Leave a Reply Cancel reply
Your email address will not be published. Required fields are marked *
Comment
Name *
Email *
Website
Notify me of follow-up comments by email.
Notify me of new posts by email.
Recommend
-
101
-
64
Change Randomly A View’s Color Hi everyone, here is the third part of the Xamarin Forms Tips series. Today, we will look at how to change a...
-
54
Hot off the press, another PR just got merged into the Xamarin.Forms repository. This time, adding a new feature on a Label, the ability to specify
-
56
For a pull request I opened on the Xamarin .Forms repository, I had imple...
-
42
A new feature was merged into the Xamarin.Forms repository. This time: TextColor for the TableSection control. With this new feature, you can specify the color of the text that is used in a table section. A small feature,...
-
38
Snack Bar in Xamarin Forms Hello friends, notifying users about what happens in your mobile application is necessary. There is the
-
28
David May 28th, 2019 Xamarin.Forms 4.0 introducedamazing new features to help streamline development when bu...
-
28
README.md
-
56
Paul October 22nd, 2019 Today we’re incredibly pleased to announce the stable release of Xamarin.Forms 4.3.0....
-
29
With the R2 2020 Release of Telerik UI for Xamarin we have extended our list of picker components with three new pickers:DatePicker,TimePickerandTimeSpan Picker. The DatePicker control for Xamarin provides the...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK