1

DatePicker基本的に、 from jrgcubanoのカスタム レンダラー実装を使用しています。ここで、UWP 用のカスタム レンダラーを提供したいと考えています。したがって、UWP でコントロールを交換し、代わりに a を使用したいと考えていますCalendarDatePicker

基本的に、プロパティDateとプロパティは同じである必要があります (nullNullableDateの場合を除く)。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。デフォルト値にリセットする可能性もあるはずです。

4

0 に答える 0