【发布时间】:2017-07-31 15:33:02
【问题描述】:
我正在使用可以为空的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;
}
}
}
我不在这里提供自定义渲染器,因为它们大多是 setter。我目前的方法有效,但是必须通过一个额外的按钮来清除所选日期,并且按下“取消”仍然会在日期选择器中设置日期。现在我想改善这种行为,并且正在寻找更好的解决方案。
问题:
- 用户应该能够从日期选择器中选择任何日期(包括今天)
- 能够清除当前选择的日期
- 取消的行为应该类似于取消(并清除日期)
- 适用于所有平台(iOS、Droid、UWP)
已经有一个feature request,但这还没有实现。还有some tries 可以解决这个问题,但是我还没有找到可以解决我所有问题的有效解决方案。
我可以使用DateSelected 事件,如果我选择今天的日期(或者最后选择的日期是准确的并且在初始化时这是今天的日期),它不会被触发。或者我每次都设置NullableDate,取消时也会显示日期。结果,如果用户按cancel,则无法清除日期。我尝试尝试Unfocused 事件,但我没有找到有用的东西。也许可以使用ViewRenderer 并交换底层的原生视图以完全控制它?但是渲染器有wrong base classes ...
有什么想法吗?
【问题讨论】:
-
创建自定义控件的想法怎么样?您可以提供额外的按钮和覆盖属性需要不同的行为。因此,不要将 DatePicker 子类化,而是将其添加为控件的成员
-
@YuriS:是的,自定义控件是一种方式。但是对于平台细节,您仍然需要自定义渲染器。
标签: c# xamarin datepicker xamarin.forms nullable