我正在使用可为空的DatePicker https://developer.xamarin.com/api/type/Xamarin.Forms.DatePicker/,它是通过子类化来实现的DatePicker
并使用自定义渲染器。
public class ExtendedDatePicker : DatePicker
{
public static readonly BindableProperty NullableDateProperty =
BindableProperty.Create(
"NullableDate",
typeof(DateTime?),
typeof(ExtendedDatePicker),
null,
BindingMode.TwoWay);
public static readonly BindableProperty PlaceholderProperty =
BindableProperty.Create(
"Placeholder",
typeof(string),
typeof(ExtendedDatePicker),
string.Empty,
BindingMode.OneWay);
public DateTime? NullableDate
{
get { return (DateTime?)GetValue(NullableDateProperty); }
set
{
if (value != NullableDate)
{
SetValue(NullableDateProperty, value);
}
}
}
public string Placeholder
{
get { return (string)GetValue(PlaceholderProperty); }
set { SetValue(PlaceholderProperty, value); }
}
public ExtendedDatePicker()
{
//this.Unfocused += ExtendedDatePicker_Unfocused;
//this.DateSelected += ExtendedDatePicker_DateSelected;
}
//private void ExtendedDatePicker_DateSelected(object sender, DateChangedEventArgs e)
//{
// NullableDate = Date;
//}
//private void ExtendedDatePicker_Unfocused(object sender, FocusEventArgs e)
//{
// if (Device.RuntimePlatform == Device.Android && !e.IsFocused)
// {
// NullableDate = Date;
// }
//}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
UpdateDate();
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == IsFocusedProperty.PropertyName)
{
if (IsFocused)
{
if (!NullableDate.HasValue)
{
Date = (DateTime)DateProperty.DefaultValue;
}
}
else
{
OnPropertyChanged(DateProperty.PropertyName);
}
}
if (propertyName == DateProperty.PropertyName)
{
if (Date != default(DateTime))
{
if (Date != NullableDate.GetValueOrDefault())
NullableDate = Date;
}
else
{
if (NullableDate != null)
NullableDate = null;
}
}
if (propertyName == NullableDateProperty.PropertyName)
{
if (NullableDate.HasValue)
{
if (Date != NullableDate.GetValueOrDefault())
Date = NullableDate.Value;
}
}
}
private void UpdateDate()
{
if (NullableDate.HasValue)
{
Date = NullableDate.Value;
}
else
{
Date = (DateTime)DateProperty.DefaultValue;
}
}
}
我在这里不提供自定义渲染器,因为它们主要是设置器。我当前的方法有效,但是必须通过额外的按钮清除所选日期,并且按“取消”仍然会在日期选择器中设置日期。现在我想改善这种行为,并且正在寻找更好的解决方案。
Issues:
- 用户应该能够从日期选择器中选择任何日期(包括今天)
- 能够清除当前选择的日期
- 取消应该像取消一样(并清除日期)
- 适用于所有平台(iOS、Droid、UWP)
已经有一个功能要求 https://xamarin.uservoice.com/forums/144858-xamarin-platform-suggestions/suggestions/16997776-xamarin-forms-datepicker-with-clear-button-to-allo,但这尚未实施。还有一些尝试 https://forums.xamarin.com/discussion/20028/datepicker-possible-to-bind-to-nullable-date-value解决这个问题,但我还没有找到一个可行的解决方案来解决我的所有问题。
我可以使用DateSelected https://developer.xamarin.com/api/event/Xamarin.Forms.DatePicker.DateSelected/事件,如果我选择今天的日期(或最后选择的日期,并且在初始化时这是今天的日期),该事件不会被触发。或者我设置NullableDate
每次和取消时也会显示日期。结果,用户按下后无法清除日期cancel。我尝试尝试Unfocused
事件,但我还没有找到有用的东西。也许人们可以使用ViewRenderer
并交换底层的本机视图以完全控制它?但渲染器有错误的基类 https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/renderers/ ...
有任何想法吗?