基本上我正在使用来自jrgcubano的DatePicker
的自定义渲染器实现。现在我想为UWP提供自定义渲染器。因此,我在UWP上交换控件,并希望改为使用CalendarDatePicker
。
基本上,属性Date
和NullableDate
应该相同(除了NullableDate
为空的情况除外)。所以有一个同步(有时会经常设置属性,但这是另一个故事)。我现在经历的是,Date
总是错误的价值。大多数情况下,它具有默认值,即当前日期(或者值为01.01.0001)。该值似乎无法更改,因为在调试模式下,它在更改为新值后仍具有相同的值。由于同步,NullableDate
在一次具有正确值后得到错误的值也会发生。要使自定义渲染器正常工作,还必须订阅DateChanged
事件。
这是我当前的实现,它显示了一个完全正常工作的项目:
MainPage.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;
}
}
ExtendedDatePicker.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
中选择的值。还应该可以重置为默认值。