基本上我正在使用DatePicker
来自jrgcubano的自定义渲染器实现。现在我想为 UWP 提供一个自定义渲染器。因此,我交换了 UWP 上的控件并想使用 aCalendarDatePicker
来代替。
基本上,属性Date
和NullableDate
应该是相同的(除了为NullableDate
空的情况)。所以有一个同步(有时设置属性过于频繁,但这是另一回事)。我现在的经验是,它Date
总是有错误的价值。大多数情况下,它具有默认值,即当前日期(或具有值 01.01.0001)。这个值好像是不能改的,因为在调试模式下改成新的值还是一样的。由于同步,它也会发生NullableDate
在一次获得正确值后得到错误值的情况。要使自定义渲染器正常工作,还需要订阅该DateChanged
事件。
这是我当前的实现,它显示了一个完整的工作项目:
主页.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"
x:Class="TestExtendedDatePicker.MainPage"
xmlns:renderer="clr-namespace:TestExtendedDatePicker;assembly=TestExtendedDatePicker"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<StackLayout>
<renderer:ExtendedDatePicker x:Name="dateOfBirth"
NullableDate="{x:Null}"
MaximumDate="{x:Static sys:DateTime.Now}">
<DatePicker.Format>dd.MM.yyyy</DatePicker.Format>
<DatePicker.MinimumDate>
<sys:DateTime x:FactoryMethod="Parse">
<x:Arguments>
<x:String>Jan 1 0001</x:String>
</x:Arguments>
</sys:DateTime>
</DatePicker.MinimumDate>
</renderer:ExtendedDatePicker>
<Button x:Name="clearButton"
Text="Reset"
Clicked="OnClearButtonClicked" />
<Button x:Name="showButton"
Text="Show values"
Clicked="OnShowButtonClicked" />
</StackLayout>
</ContentPage>
MainPage.xaml.cs
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
private void OnShowButtonClicked(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Date: " + this.dateOfBirth.Date);
System.Diagnostics.Debug.WriteLine("NullableDate: " + this.dateOfBirth.NullableDate);
return;
}
private void OnClearButtonClicked(object sender, EventArgs e)
{
this.dateOfBirth.NullableDate = null;
}
}
扩展日期选择器.cs
public class ExtendedDatePicker : DatePicker
{
public static readonly BindableProperty NullableDateProperty =
BindableProperty.Create("NullableDate", typeof(DateTime?), typeof(ExtendedDatePicker), null, BindingMode.TwoWay);
public DateTime? NullableDate
{
get { return (DateTime?)GetValue(NullableDateProperty); }
set
{
if (value != NullableDate)
{
SetValue(NullableDateProperty, value);
UpdateDate();
}
}
}
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
UpdateDate();
}
protected override void OnPropertyChanged(string propertyName = null)
{
base.OnPropertyChanged(propertyName);
if (propertyName == DateProperty.PropertyName)
{
if (Date != default(DateTime))
{
NullableDate = Date;
}
else
{
NullableDate = null;
}
}
if (propertyName == NullableDateProperty.PropertyName)
{
if (NullableDate.HasValue && Date != NullableDate.Value)
{
Date = NullableDate.Value;
}
}
}
private void UpdateDate()
{
if (NullableDate.HasValue)
{
Date = NullableDate.Value;
}
else
{
Date = (DateTime)DateProperty.DefaultValue;
//Date = default(DateTime);
}
}
}
ExtendedDatePickerRenderer.cs
public class ExtendedDatePickerRenderer : ViewRenderer<Xamarin.Forms.DatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.DatePicker> e)
{
base.OnElementChanged(e);
var view = Element as ExtendedDatePicker;
if (e.OldElement != null || view == null)
return;
var calendarDatePicker = new CalendarDatePicker();
calendarDatePicker.DateChanged += CalendarDatePicker_DateChanged;
SetNativeControl(calendarDatePicker);
SetNullableText(view);
}
private void CalendarDatePicker_DateChanged(CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs args)
{
var view = this.Element as ExtendedDatePicker;
if (args.NewDate.HasValue)
{
DateTime newDate = args.NewDate.GetValueOrDefault().LocalDateTime.Date;
view.NullableDate = newDate;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
var view = (ExtendedDatePicker)Element;
if (e.PropertyName == ExtendedDatePicker.NullableDateProperty.PropertyName)
SetNullableText(view);
}
private void SetNullableText(ExtendedDatePicker view)
{
if (view.NullableDate == null)
Control.Date = null;
}
}
我必须更改与Date
具有相同值的内容NullableDate
?并且该值应该代表在DatePicker
. 还应该有可能重置为默认值。