using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; using Avalonia.Input; using Avalonia.Interactivity; using System; using System.Collections.Generic; using System.Globalization; namespace Avalonia.Controls { /// /// Defines the presenter used for selecting a date for a /// /// public class DatePickerPresenter : PickerPresenterBase { /// /// Defines the Property /// public static readonly DirectProperty DateProperty = AvaloniaProperty.RegisterDirect(nameof(Date), x => x.Date, (x, v) => x.Date = v); /// /// Defines the Property /// public static readonly DirectProperty DayFormatProperty = DatePicker.DayFormatProperty.AddOwner(x => x.DayFormat, (x, v) => x.DayFormat = v); /// /// Defines the Property /// public static readonly DirectProperty DayVisibleProperty = DatePicker.DayVisibleProperty.AddOwner(x => x.DayVisible, (x, v) => x.DayVisible = v); /// /// Defines the Property /// public static readonly DirectProperty MaxYearProperty = DatePicker.MaxYearProperty.AddOwner(x => x.MaxYear, (x, v) => x.MaxYear = v); /// /// Defines the Property /// public static readonly DirectProperty MinYearProperty = DatePicker.MinYearProperty.AddOwner(x => x.MinYear, (x, v) => x.MinYear = v); /// /// Defines the Property /// public static readonly DirectProperty MonthFormatProperty = DatePicker.MonthFormatProperty.AddOwner(x => x.MonthFormat, (x, v) => x.MonthFormat = v); /// /// Defines the Property /// public static readonly DirectProperty MonthVisibleProperty = DatePicker.MonthVisibleProperty.AddOwner(x => x.MonthVisible, (x, v) => x.MonthVisible = v); /// /// Defines the Property /// public static readonly DirectProperty YearFormatProperty = DatePicker.YearFormatProperty.AddOwner(x => x.YearFormat, (x, v) => x.YearFormat = v); /// /// Defines the Property /// public static readonly DirectProperty YearVisibleProperty = DatePicker.YearVisibleProperty.AddOwner(x => x.YearVisible, (x, v) => x.YearVisible = v); // Template Items private Grid? _pickerContainer; private Button? _acceptButton; private Button? _dismissButton; private Rectangle? _spacer1; private Rectangle? _spacer2; private Panel? _monthHost; private Panel? _yearHost; private Panel? _dayHost; private DateTimePickerPanel? _monthSelector; private DateTimePickerPanel? _yearSelector; private DateTimePickerPanel? _daySelector; private Button? _monthUpButton; private Button? _dayUpButton; private Button? _yearUpButton; private Button? _monthDownButton; private Button? _dayDownButton; private Button? _yearDownButton; private DateTimeOffset _date; private string _dayFormat = "%d"; private bool _dayVisible = true; private DateTimeOffset _maxYear; private DateTimeOffset _minYear; private string _monthFormat = "MMMM"; private bool _monthVisible = true; private string _yearFormat = "yyyy"; private bool _yearVisible = true; private DateTimeOffset _syncDate; private readonly GregorianCalendar _calendar; private bool _suppressUpdateSelection; public DatePickerPresenter() { var now = DateTimeOffset.Now; _minYear = new DateTimeOffset(now.Year - 100, 1, 1, 0, 0, 0, now.Offset); _maxYear = new DateTimeOffset(now.Year + 100, 12, 31, 0, 0, 0, now.Offset); _date = now; _calendar = new GregorianCalendar(); KeyboardNavigation.SetTabNavigation(this, KeyboardNavigationMode.Cycle); } /// /// Gets or sets the current Date for the picker /// public DateTimeOffset Date { get => _date; set { SetAndRaise(DateProperty, ref _date, value); _syncDate = Date; InitPicker(); } } /// /// Gets or sets the DayFormat /// public string DayFormat { get => _dayFormat; set => SetAndRaise(DayFormatProperty, ref _dayFormat, value); } /// /// Get or sets whether the Day selector is visible /// public bool DayVisible { get => _dayVisible; set { SetAndRaise(DayVisibleProperty, ref _dayVisible, value); } } /// /// Gets or sets the maximum pickable year /// public DateTimeOffset MaxYear { get => _maxYear; set { if (value < MinYear) throw new InvalidOperationException("MaxDate cannot be less than MinDate"); SetAndRaise(MaxYearProperty, ref _maxYear, value); if (Date > value) Date = value; } } /// /// Gets or sets the minimum pickable year /// public DateTimeOffset MinYear { get => _minYear; set { if (value > MaxYear) throw new InvalidOperationException("MinDate cannot be greater than MaxDate"); SetAndRaise(MinYearProperty, ref _minYear, value); if (Date < value) Date = value; } } /// /// Gets or sets the month format /// public string MonthFormat { get => _monthFormat; set => SetAndRaise(MonthFormatProperty, ref _monthFormat, value); } /// /// Gets or sets whether the month selector is visible /// public bool MonthVisible { get => _monthVisible; set { SetAndRaise(MonthVisibleProperty, ref _monthVisible, value); } } /// /// Gets or sets the year format /// public string YearFormat { get => _yearFormat; set => SetAndRaise(YearFormatProperty, ref _yearFormat, value); } /// /// Gets or sets whether the year selector is visible /// public bool YearVisible { get => _yearVisible; set { SetAndRaise(YearVisibleProperty, ref _yearVisible, value); } } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); // These are requirements, so throw if not found _pickerContainer = e.NameScope.Get("PickerContainer"); _monthHost = e.NameScope.Get("MonthHost"); _dayHost = e.NameScope.Get("DayHost"); _yearHost = e.NameScope.Get("YearHost"); _monthSelector = e.NameScope.Get("MonthSelector"); _monthSelector.SelectionChanged += OnMonthChanged; _daySelector = e.NameScope.Get("DaySelector"); _daySelector.SelectionChanged += OnDayChanged; _yearSelector = e.NameScope.Get("YearSelector"); _yearSelector.SelectionChanged += OnYearChanged; _acceptButton = e.NameScope.Get