android - 如何捕获已在 Xamarin Forms (Android) DatePicker 上选择的默认日期?
问题描述
Currently, the DatePicker does not fire the DateSelected event when the default date is chosen. 我需要能够捕获选择日期的时间,无论它是默认日期还是任何其他日期,以便相应地更新我的数据。
解决方案
在网络上从其他人那里获得想法后,我使用了一个 Button、一个适用于 Android 和 iOS 的 DatePickerRenderer,以及 MessagingCenter。但是,我不确定这是否是一个正确的解决方案,尤其是关于 MessagingCenter 的内存泄漏 - 请随时发表评论。请参阅以下解决方案的示例代码:
Page XAML //共享项目
<?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:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="MyDatePickerApp.PickDatePage">
<ContentPage.Content>
<StackLayout VerticalOptions="Center" Margin="20">
<Button x:Name="StartDateBtn"
Text="Start Date"
BackgroundColor="Silver"
TextColor="White"
Clicked="StartDateBtn_Clicked"
VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/>
<DatePicker x:Name="StartDatePicker"
IsEnabled="True"
IsVisible="False"/>
</StackLayout>
</ContentPage.Content>
代码隐藏页面 //共享项目
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace MyDatePickerApp
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class PickDatePage : ContentPage
{
public PickDatePage()
{
InitializeComponent();
MessagingCenter.Subscribe<DatePicker>(this, "OK", (sender) => {
UpdateDate(sender); });
MessagingCenter.Subscribe<DatePicker>(this, "Cancelled", (sender) => {
CancelDate(sender); });
MessagingCenter.Subscribe<DatePicker>(this, "Cleared", (sender) => {
ClearDate(sender); });
}
private void StartDateBtn_Clicked(object sender, EventArgs e)
{
StartDateBtn.InputTransparent = true;
StartDatePicker.MinimumDate = DateTime.Now.AddDays(-90);
StartDatePicker.MaximumDate = DateTime.Now.AddYears(3);
StartDatePicker.Format = "MM/dd/yyyy";
if(StartDateBtn.Text != "Start Date")
{
var tmpDateString = StartDateBtn.Text;
var tmpDateStringSub = tmpDateString.Substring(12);
StartDatePicker.Date = Convert.ToDateTime(tmpDateStringSub);
}
else
{
StartDatePicker.Date = DateTime.Now;
}
StartDatePicker.Focus();
}
private void UpdateDate(DatePicker sender)
{
var myDP = sender;
var rawDate = StartDatePicker.Date;
StartDateBtn.Text = "Start Date: " + rawDate.ToString("MM/dd/yyyy");
StartDatePicker.Unfocus();
StartDateBtn.InputTransparent = false;
}
private void ClearDate(DatePicker sender)
{
var myDP = sender;
StartDateBtn.Text = "Start Date";
StartDatePicker.Unfocus();
StartDateBtn.InputTransparent = false;
}
private void CancelDate(DatePicker sender)
{
var myDP = sender;
StartDatePicker.Unfocus();
StartDateBtn.InputTransparent = false;
}
protected override void OnDisappearing()
{
MessagingCenter.Unsubscribe<DatePicker>(this, "OK");
MessagingCenter.Unsubscribe<DatePicker>(this, "Cancelled");
MessagingCenter.Unsubscribe<DatePicker>(this, "Cleared");
base.OnDisappearing();
}
}
}
Android DatePickerRenderer //Android项目
using Android.App;
using Android.Content;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using MyDatePickerApp.Droid;
[assembly:ExportRenderer(typeof(Xamarin.Forms.DatePicker),
typeof(ADatePickerRenderer))]
namespace MyDatePickerApp.Droid
{
public class ADatePickerRenderer : DatePickerRenderer
{
public ADatePickerRenderer(Context context) : base(context)
{
}
protected override DatePickerDialog CreateDatePickerDialog(int year, int month, int day)
{
Xamarin.Forms.DatePicker view = (Xamarin.Forms.DatePicker)Element;
var dialog = new DatePickerDialog(Context, (o, e) =>{}, year, month, day);
dialog.SetButton("OK", (sender, e) => { var nativePickerDialog = (Android.App.DatePickerDialog)sender; view.Date = nativePickerDialog.DatePicker.DateTime; MessagingCenter.Send(view, "OK"); });
dialog.SetButton2("Cancel", (sender, e) => { var nativePickerDialog =(Android.App.DatePickerDialog)sender; view.Date =nativePickerDialog.DatePicker.DateTime; MessagingCenter.Send(view, "Cancelled"); });
dialog.SetButton3("Clear", (sender, e) => { var nativePickerDialog =(Android.App.DatePickerDialog)sender; view.Date = nativePickerDialog.DatePicker.DateTime; MessagingCenter.Send(view, "Cleared"); });
return dialog;
//return base.CreateDatePickerDialog(year, month, day);
}
}
}
iOS DatePickerRenderer //iOS 项目
using System.Collections.Generic;
using System.Linq;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
using MyDatePickerApp.iOS;
[assembly: ExportRenderer(typeof(Xamarin.Forms.DatePicker), typeof(iosDatePickerRenderer))]
namespace MyDatePickerApp.iOS
{
public class iosDatePickerRenderer : DatePickerRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged(e);
if (e.NewElement != null && Control != null)
{
var view = Element;
var tbar = Control.InputAccessoryView as UIToolbar;
var origItems = tbar.Items;
var newItems = new List<UIBarButtonItem>();
if (origItems.Count() < 3)
{
var clearItem = new UIBarButtonItem("Clear", UIBarButtonItemStyle.Plain, (sender, ev) =>{ MessagingCenter.Send(view, "Cleared"); });
newItems.Add(clearItem);
var flexspace = new UIBarButtonItem(UIBarButtonSystemItem.FlexibleSpace);
newItems.Add(flexspace);
var cancelItem = new UIBarButtonItem("Cancel", UIBarButtonItemStyle.Plain, (sender, ev) =>{ MessagingCenter.Send(view, "Cancelled"); });
newItems.Add(cancelItem);
var OKItem = new UIBarButtonItem("Done", UIBarButtonItemStyle.Plain, (sender, ev) => { MessagingCenter.Send(view, "OK"); });
newItems.Add(OKItem);
tbar.Items = newItems.ToArray();
}
}
}
}
}
推荐阅读
- google-ads-api - Google ADs API:即使在状态为 OK 后也没有得到响应的广告系列列表
- string - 使用 find + cat 获取我“grep”的文件
- javascript - 仅在 javascript 中将日期和时间的结构转换为时间
- javascript - Is it possible to change existing code to set button to disable/enable state without refresh the page?
- javascript - Babel 转译 javascript 并在输出周围添加一个 define([], function(){})。我该如何防止这种情况?
- camera - 从 PointCloud2 到 pcl
- excel - 在具有多个工作表的工作簿中搜索特定值并将整行粘贴复制到新工作簿
- c# - 用 FakeItEasy 和 DBContext 模拟不起作用
- github - 如何在创建时向 GitHub 组织名称添加验证?
- typescript - 使用 Svelte 和 TypeScript 向 HTMLElements 添加类型