Xamarin.Forms Android DatePicker/TimePicker button listener
Asked Answered
B

3

4

I need to know if a user tapped on the Cancel or Ok button in a Date/Time picker of an xamarin.Forms Android app.

I have tried to add a function to the Click event but this is never triggered.

This is my code (similar for the TimePicker):

using Android.Content;
using MyApp.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using MyApp.Models;
using Java.Util;

[assembly: ExportRenderer(typeof(DatePicker), typeof(DatePickerCustomRenderer))]

namespace MyApp.Droid {
    public class DatePickerCustomRenderer : DatePickerRenderer {

        public DatePickerCustomRenderer(Context context) : base(context) { } 

        protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e) {
            base.OnElementChanged(e);

            Locale locale = new Locale(Utente.FormatoPerDateTimePicker);
            Control.TextLocale = locale;

            Control.Click += Control_Click;
        }

        private void Control_Click(object sender, System.EventArgs e) {
            // This function is never called :(
            throw new System.NotImplementedException();
        }
    }
}

How can I do this?

Bakki answered 27/2, 2018 at 12:50 Comment(0)
P
2

I need to know if a user tapped on the "cancel" or on the "ok" button in a date/time picker of an xamarin.Forms Android app.

With Xamarin.Form's DatePicker, you can't do that. Xamarin.Forms.DatePicker is renderered into an EditText control. The pop up DatePickerDialog is unfortunately not exposed to user. You can see that from Source Codes of DatePickerRenderer.

So if you really want to detect the OK/Cancel button click events. You need to implement your own DatePickerRenderer according to the source codes.

Prison answered 28/2, 2018 at 7:51 Comment(2)
Oh :( Thank you.Bakki
@elvis-xia-msft i got only cancel click event for date picker from your sample. I need to get OK click event. OnElement property changed override method invoked when changeing the date. But first time open date picker and when click on OK button, no event called.Waggoner
A
3

Using the following Android DatePicker custom renderer you have total control over OK and CANCEL.

using Android.App;
using Android.Content;
using ???.Android.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using DatePicker = Xamarin.Forms.DatePicker;

[assembly: ExportRenderer(typeof(DatePicker), typeof(FixedDatePickerRenderer))]    
namespace ???.Android.Renderers
{
    public class FixedDatePickerRenderer : Xamarin.Forms.Platform.Android.DatePickerRenderer
    {
        public FixedDatePickerRenderer(Context context) : base(context)
        {
        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.DatePicker> e)
        {
            base.OnElementChanged(e);

            //Disposing
            if (e.OldElement != null)
            {
                _element = null;
            }

            //Creating
            if (e.NewElement != null)
            {
                _element = e.NewElement;
            }
        }

        protected Xamarin.Forms.DatePicker _element;

        protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
        {
            var dialog = new DatePickerDialog(Context, (o, e) =>
            {
                _element.Date = e.Date;
                ((IElementController)_element).SetValueFromRenderer(VisualElement.IsFocusedPropertyKey, false);
            }, year, month, day);

            dialog.SetButton((int)DialogButtonType.Positive, Context.Resources.GetString(global::Android.Resource.String.Ok), OnOk);
            dialog.SetButton((int)DialogButtonType.Negative, Context.Resources.GetString(global::Android.Resource.String.Cancel), OnCancel);

            return dialog;
        }

        private void OnCancel(object sender, DialogClickEventArgs e)
        {
            _element.Unfocus();
            //((FixedDatePicker) _element)?.CallOnCancel();
        }
        private void OnOk(object sender, DialogClickEventArgs e)
        {
            //need to set date from native control manually now
            _element.Date = ((DatePickerDialog)sender).DatePicker.DateTime;
            _element.Unfocus();
            //((FixedDatePicker)_element)?.CallOnOk();
        }

    }

}


 

Just for people looking for a complete solution to avoid searching for iOS, there's an option already included out-of-the box: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/platform/ios/datepicker-selection

Americaamerican answered 21/3, 2020 at 10:48 Comment(0)
P
2

I need to know if a user tapped on the "cancel" or on the "ok" button in a date/time picker of an xamarin.Forms Android app.

With Xamarin.Form's DatePicker, you can't do that. Xamarin.Forms.DatePicker is renderered into an EditText control. The pop up DatePickerDialog is unfortunately not exposed to user. You can see that from Source Codes of DatePickerRenderer.

So if you really want to detect the OK/Cancel button click events. You need to implement your own DatePickerRenderer according to the source codes.

Prison answered 28/2, 2018 at 7:51 Comment(2)
Oh :( Thank you.Bakki
@elvis-xia-msft i got only cancel click event for date picker from your sample. I need to get OK click event. OnElement property changed override method invoked when changeing the date. But first time open date picker and when click on OK button, no event called.Waggoner
R
1

Nick Kovalsky' solution (using a custom renderer) above for Android works fine for me.

For iOS, the iOS specifics out-of-the-box solution didn't work for me, https://learn.microsoft.com/en-us/xamarin/xamarin-forms/platform/ios/datepicker-selection

I've used the custom renderer approach for iOS also, Looking at the Xamarin custom renderer (On iOS platform), we can see the InputAccessoryView is set to UIToolbar, and the toolbar contains the Done button (UIBarButtonItem). So, we can use the Done button and listen for click event,
https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Platform.iOS/Renderers/DatePickerRenderer.cs

[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(MyApp.iOS.CustomRenderers.CustomDatePickerRenderer))]
public class CustomDatePickerRenderer : DatePickerRenderer
    {      
        CustomDatePicker _datePickerElement ;

        protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement is CustomDatePicker datePickerElement && Control != null)
            {
                _datePickerElement = datePickerElement;                

                var toolbar = Control.InputAccessoryView as UIToolbar;
                foreach (var button in toolbar?.Items)
                {
                    if (button.Style == UIBarButtonItemStyle.Done)
                    {
                        button.Clicked -= OnDoneButtonClicked;
                        button.Clicked += OnDoneButtonClicked;
                    }
                }
            }
        }

        private void OnDoneButtonClicked(object sender, EventArgs e)
        {
            if(_datePickerElement.NullableDate != _datePickerElement.Date)
            {
                _datePickerElement.NullableDate = _datePickerElement.Date;
            }            
        }

    }
Radiotelegram answered 23/4, 2020 at 15:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.