C# Xamarin Forms DateTimePicker自定义ContentView可绑定属性

C# Xamarin Forms DateTimePicker自定义ContentView可绑定属性,c#,xamarin.forms,mvvm,datetimepicker,C#,Xamarin.forms,Mvvm,Datetimepicker,根据这篇文章的公认答案,我构建了以下自定义DateTimePicker:, 以选择日期和时间 日期时间选择器类: using System; using System.ComponentModel; using Xamarin.Forms; namespace NativeTaskApp.Views.Component { public class DateTimePicker : ContentView, INotifyPropertyChanged { pu

根据这篇文章的公认答案,我构建了以下自定义DateTimePicker:, 以选择日期和时间

日期时间选择器类:

using System;
using System.ComponentModel;
using Xamarin.Forms;

namespace NativeTaskApp.Views.Component
{
    public class DateTimePicker : ContentView, INotifyPropertyChanged
    {
        public Entry _entry { get; private set; } = new Entry();
        public DatePicker _datePicker { get; private set; } = new DatePicker() { Date = DateTime.Today, IsVisible = false };
        public TimePicker _timePicker { get; private set; } = new TimePicker() { IsVisible = false };
        string _stringFormat { get; set; }
        public string StringFormat { get { return _stringFormat ?? "dd/MM/yyyy HH:mm"; } set { _stringFormat = value; } }
        
        public DateTime DateTime
        {
            get { return (DateTime)GetValue(DateTimeProperty); }
            set { SetValue(DateTimeProperty, value); OnPropertyChanged("DateTime"); }
        }

        private TimeSpan _time
        {
            get
            {
                return TimeSpan.FromTicks(DateTime.Ticks);
            }
            set
            {
                DateTime = new DateTime(DateTime.Date.Ticks).AddTicks(value.Ticks);
            }
        }

        private DateTime _date
        {
            get
            {
                return DateTime.Date;
            }
            set
            {
                DateTime = new DateTime(DateTime.TimeOfDay.Ticks).AddTicks(value.Ticks);
            }
        }

        BindableProperty DateTimeProperty = BindableProperty.Create("DateTime", typeof(DateTime), typeof(DateTimePicker), DateTime.Now, BindingMode.TwoWay, propertyChanged: DTPropertyChanged);

        [Obsolete]
        public DateTimePicker()
        {
            BindingContext = this;

            Content = new StackLayout()
            {
                Children =
            {
                _datePicker,
                _timePicker,
                _entry
            }
            };

            _datePicker.SetBinding<DateTimePicker>(DatePicker.DateProperty, p => p._date);
            _timePicker.SetBinding<DateTimePicker>(TimePicker.TimeProperty, p => p._time);
            _timePicker.Unfocused += (sender, args) => _time = _timePicker.Time;
            _datePicker.Focused += (s, a) => UpdateEntryText();

            GestureRecognizers.Add(new TapGestureRecognizer()
            {
                Command = new Command(() => _datePicker.Focus())
            });
            _entry.Focused += (sender, args) =>
            {
                Device.BeginInvokeOnMainThread(() => _datePicker.Focus());
            };
            _datePicker.Unfocused += (sender, args) =>
            {
                Device.BeginInvokeOnMainThread(() =>
                {
                    _timePicker.Focus();
                    _date = _datePicker.Date;
                    UpdateEntryText();
                });
            };
        }

        private void UpdateEntryText()
        {
            _entry.Text = DateTime.ToString(StringFormat);
        }

        static void DTPropertyChanged(BindableObject bindable, object oldValue, object newValue)
        {
            var timePicker = (bindable as DateTimePicker);
            timePicker.UpdateEntryText();
        }
    }
}
Xaml绑定上下文

using NativeTaskApp.Services.GeneratedClients;
using System;
using System.Collections.Generic;
using Xamarin.Forms;

namespace NativeTaskApp.ViewModels
{
    public class CreateVM : BaseViewModel
    {
        /*Task.Schedules = new List<Schedule>*/
        /*Schedule.Date = DateTime*/
        public Todo Task { get; set; }
        public DateTime NewScheduleDate { get; set; }



        public Command AddScheduleCommand { get; }
        public CreateVM()
        {
            Task = new Todo();
            Task.Schedules = new List<Schedule>();
            NewScheduleDate = DateTime.Now;

            AddScheduleCommand = new Command(AddSchedule);
        }




        public void AddSchedule()
        {
            Task.Schedules.Add(new Schedule() { Date = NewScheduleDate });
        }
    }
}
使用NativeTaskApp.Services.GeneratedClients;
使用制度;
使用System.Collections.Generic;
使用Xamarin.Forms;
名称空间NativeTaskApp.ViewModels
{
公共类CreateVM:BaseViewModel
{
/*Task.Schedules=新列表*/
/*Schedule.Date=DateTime*/
公共待办事项任务{get;set;}
public DateTime NewScheduleDate{get;set;}
公共命令AddScheduleCommand{get;}
公共CreateVM()
{
任务=新Todo();
Task.Schedules=新列表();
NewScheduleDate=DateTime.Now;
AddScheduleCommand=新命令(AddSchedule);
}
公众假期表()
{
Add(newschedule(){Date=NewScheduleDate});
}
}
}
1。DateTime作为可绑定属性 也许我误解了前面的答案,但事实上,DateTime是一个可绑定的属性,我们每天都在移动应用程序的特定控件中使用它

声明示例:

public static readonly BindableProperty MinimumDateProperty = BindableProperty.Create(nameof(MinimumDate),
typeof(DateTime),
typeof(DateTime), default(DateTime), BindingMode.OneWay, propertyChanged: OnYearsRangeChanged);
public static readonly BindableProperty DateTimeProperty = BindableProperty.Create("DateTime", typeof(DateTime), typeof(DateTimePicker), DateTime.Now, BindingMode.TwoWay, propertyChanged: DTPropertyChanged) 
我们在xaml中这样使用它:

<controls:MonthYearPicker 
 MinimumDate="{Binding TodayDateTime}"
 MaximumDate="{Binding ExitDateTime}"
 SelectedDateTime="{Binding SelectedExitLocalDate}"/>
似乎是内部的而非公开的:()

添加公共访问说明符并查看错误消息是否仍然存在

例如:

public static readonly BindableProperty MinimumDateProperty = BindableProperty.Create(nameof(MinimumDate),
typeof(DateTime),
typeof(DateTime), default(DateTime), BindingMode.OneWay, propertyChanged: OnYearsRangeChanged);
public static readonly BindableProperty DateTimeProperty = BindableProperty.Create("DateTime", typeof(DateTime), typeof(DateTimePicker), DateTime.Now, BindingMode.TwoWay, propertyChanged: DTPropertyChanged) 

除此之外,要将DateTime用作可绑定属性,请删除BindingContext=this行