Invoking DatePickerDialog asynchronously with Xamarin.Android

Invoking a DatePickerDialog in Xamarin.Android is a bit tricky because it is done through callbacks and at the end one has to dispose it as well. Hence I present asynchronous extension methods PickDateAsync and PickDateAndAssignAsync.

With my code you can use this syntax and don’t worry about DatePickerDialog disposal:

EditText et1 = FindViewById<EditText>(Resource.Id.editText1);
await et1.PickDateAndAssignAsync();

There is also an overload that accepts an instance of CancellationToken. Here are the methods:

public static class DatePickerExtension
{
    public static Task<DateTime> PickDateAsync(this EditText dateEdit)
    {
        return dateEdit.PickDateAsync(CancellationToken.None);
    }
    public static Task<DateTime> PickDateAsync(this EditText dateEdit, CancellationToken ct)
    {
        TaskCompletionSource<DateTime> tsc = new TaskCompletionSource<DateTime>();
        DatePickerDialog picker = null;
        DateTime current;
        if (!DateTime.TryParse(dateEdit.Text, out current))
            current = DateTime.Now;
        picker = new DatePickerDialog(dateEdit.Context, (sender, e) =>
        {
            if (tsc != null)
            {
                if (ct.IsCancellationRequested)
                {
                    tsc.SetCanceled();
                }
                else
                {
                    tsc.SetResult(e.Date);
                }
                tsc = null;
                picker.Dispose();
            }
        }, current.Year,current.Month-1,current.Day);
        picker.Show();
        return tsc.Task;
    }

    public static Task PickDateAndAssignAsync(this EditText dateEdit)
    {
        return dateEdit.PickDateAndAssignAsync(CancellationToken.None);
    }
    public static async Task PickDateAndAssignAsync(this EditText dateEdit, CancellationToken ct)
    {
        DateTime date = await dateEdit.PickDateAsync(ct);
        if (!ct.IsCancellationRequested)
        {
            dateEdit.Text = date.ToString("d");
        }
    }
}

Enjoy awesome asynchronous C#/.net support.

Leave a Reply