我使用可以为空的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。我当前的方法有效,但必须通过一个额外的按钮清除所选日期,然后按"取消"仍然在datepicker中设置日期。现在我想改善这种行为,并且我正在寻找更好的解决方案。
的问题:
已经有feature request,但目前还没有实施。还有some tries来解决这个问题,但我还没有找到一个可行的解决方案,它解决了我的所有问题。
要么我可以使用DateSelected
事件,如果我选择今天的日期(或最后选择的日期是准确的,并且在初始化时这是今天的日期),则不会被触发。或者我每次都设置NullableDate
,在取消时也会显示日期。因此,如果用户按取消,则用户无法清除日期。我试图尝试Unfocused
事件,但我还没有找到有用的东西。也许可以使用ViewRenderer
并交换底层的原生视图来完全控制它?但是渲染器有wrong base classes ......
有什么想法吗?
答案 0 :(得分:0)
我找到了解决方案。为此付出了很多努力。
无需监听DateSelected或Unfocused事件。
基本上,我们在ExtendedDatePicker中创建一个事件,然后在完成/取消单击可能的UpdateDate方法或根据您设置日期的流程时调用此事件。
现在在使用ExtendedDatePicker的视图中,.cs文件中的侦听OnDateSelected事件。
示例:
.xaml文件:
<xyz:BorderlessDatePicker x:Name="drawCalender" Format="dd-MMM-yyyy" />
.xaml.cs文件:
drawCalender.OnDateSelected += (object sender, DateChangedEventArgs e) =>
{
ExtendedDatePicker calendarPicker = (ExtendedDatePicker)sender;
if (calendarPicker.NullableDate != null)
{
CalendarText = (DateTime)calendarPicker.NullableDate;
}
else
{
CalendarText = null;
}
};
ExtendedDatePicker类:
public class ExtendedDatePicker : DatePicker
{
public delegate void DateSelectedHandler(object sender, DateChangedEventArgs e);
public event DateSelectedHandler OnDateSelected;
public static readonly BindableProperty NullableDateProperty =
BindableProperty.Create(
"NullableDate",
typeof(DateTime?),
typeof(ExtendedDatePicker),
null,
BindingMode.TwoWay);
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;
}
OnDateSelected(this, null);
}
}
希望这会有所帮助。