A more friendly Xamarin Forms DatePicker
This is a small, simple thing, to make a Xamarin Forms DatePicker more friendly. Instead of showing the date for yesterday, today and tomorrow, as it normally does, it instead shows “yesterday”, “today”, and, you guessed it, “tomorrow”:
iOS: Android:
The view is totally straight-forward, except that instead of just binding the Date in the DatePicker, I also bind the Format:
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:FriendlyDatePicker"
x:Class="FriendlyDatePicker.FriendlyDatePickerPage"
BindingContext="{x:Static local:ViewModel.Instance}">
<DatePicker Date="{Binding TheDate}" Format="{Binding DateFormat}"/>
</ContentPage>
The View Model’s Format property looks at the date, and returns the appropriate (escaped) string:
namespace FriendlyDatePicker {
public class ViewModel : INotifyPropertyChanged {
public static ViewModel Instance { get; } = new ViewModel();
public event PropertyChangedEventHandler PropertyChanged;
DateTime theDate = DateTime.Now;
public DateTime TheDate {
get {
return theDate;
}
set {
theDate = value;
OnPropertyChanged();
OnPropertyChanged(nameof(DateFormat));
}
}
public string DateFormat {
get {
var date = DateTime.Now.Date;
if (theDate.Date == date) {
return Escape("Today");
}
if (theDate.Date == date.AddDays(1)) {
return Escape("Tomorrow");
}
return theDate.Date == date.AddDays(-1) ? Escape("Yesterday") : "d";
}
}
private string Escape(string s) {
var result = new StringBuilder();
foreach (var c in s) {
result.Append(&'\\&');
result.Append(c);
}
return result.ToString();
}
void OnPropertyChanged([CallerMemberName] string propertyName = null) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I’ve noticed that this doesn’t work in UWP apps because the DatePicker renders as a native component, and ignores the Format.
It is trivial, but does make for a nicer UX.
That’s all folks, nothing more to see, move along now.