Reputation: 599
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?
Upvotes: 4
Views: 3976
Reputation: 6462
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
Upvotes: 3
Reputation: 11
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;
}
}
}
Upvotes: 1
Reputation: 10831
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.
Upvotes: 2