Xamarin.Forms Android DatePicker/TimePicker 按钮侦听器
Xamarin.Forms Android DatePicker/TimePicker button listener
我需要知道用户是否点击了 取消 或 确定 按钮
在 Date/Time 选择器 的 xamarin.Forms
Android 应用中。
我曾尝试向 Click 事件添加一个函数,但从未触发过。
这是我的代码(类似于 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();
}
}
}
我该怎么做?
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.
对于 Xamarin.Form 的 DatePicker
,您不能这样做。 Xamarin.Forms.DatePicker
渲染到 EditText
控件中。不幸的是,弹出窗口 DatePickerDialog
没有暴露给用户。从 Source Codes of DatePickerRenderer.
可以看出
所以如果你真的想检测OK/Cancel按钮点击事件。你需要根据源码实现自己的DatePickerRenderer
使用以下 Android DatePicker 自定义呈现器,您可以完全控制确定和取消。
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();
}
}
}
仅供寻求完整解决方案以避免搜索 iOS 的用户使用,其中包含一个开箱即用的选项:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/platform/ios/datepicker-selection
Nick Kovalsky 上面针对 Android 的解决方案(使用自定义渲染器)对我来说效果很好。
对于 iOS,iOS 具体的现成解决方案对我不起作用,
https://docs.microsoft.com/en-us/xamarin/xamarin-forms/platform/ios/datepicker-selection
我也为 iOS 使用了自定义渲染器方法,
查看 Xamarin 自定义渲染器(在 iOS 平台上),我们可以看到 InputAccessoryView 设置为 UIToolbar,并且工具栏包含完成按钮 (UIBarButtonItem)。所以,我们可以使用完成按钮并监听点击事件,
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;
}
}
}
我需要知道用户是否点击了 取消 或 确定 按钮
在 Date/Time 选择器 的 xamarin.Forms
Android 应用中。
我曾尝试向 Click 事件添加一个函数,但从未触发过。
这是我的代码(类似于 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();
}
}
}
我该怎么做?
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.
对于 Xamarin.Form 的 DatePicker
,您不能这样做。 Xamarin.Forms.DatePicker
渲染到 EditText
控件中。不幸的是,弹出窗口 DatePickerDialog
没有暴露给用户。从 Source Codes of DatePickerRenderer.
所以如果你真的想检测OK/Cancel按钮点击事件。你需要根据源码实现自己的DatePickerRenderer
使用以下 Android DatePicker 自定义呈现器,您可以完全控制确定和取消。
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();
}
}
}
仅供寻求完整解决方案以避免搜索 iOS 的用户使用,其中包含一个开箱即用的选项:https://docs.microsoft.com/en-us/xamarin/xamarin-forms/platform/ios/datepicker-selection
Nick Kovalsky 上面针对 Android 的解决方案(使用自定义渲染器)对我来说效果很好。
对于 iOS,iOS 具体的现成解决方案对我不起作用, https://docs.microsoft.com/en-us/xamarin/xamarin-forms/platform/ios/datepicker-selection
我也为 iOS 使用了自定义渲染器方法,
查看 Xamarin 自定义渲染器(在 iOS 平台上),我们可以看到 InputAccessoryView 设置为 UIToolbar,并且工具栏包含完成按钮 (UIBarButtonItem)。所以,我们可以使用完成按钮并监听点击事件,
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;
}
}
}