|
|
@@ -1,6 +1,5 @@
|
|
|
using Avalonia.Controls.Metadata;
|
|
|
using Avalonia.Controls.Primitives;
|
|
|
-using Avalonia.Controls.Shapes;
|
|
|
using Avalonia.Input;
|
|
|
using Avalonia.Interactivity;
|
|
|
using System;
|
|
|
@@ -13,23 +12,23 @@ namespace Avalonia.Controls
|
|
|
/// Defines the presenter used for selecting a date for a
|
|
|
/// <see cref="DatePicker"/>
|
|
|
/// </summary>
|
|
|
- [TemplatePart("PART_AcceptButton", typeof(Button), IsRequired = true)]
|
|
|
- [TemplatePart("PART_DayDownButton", typeof(RepeatButton))]
|
|
|
- [TemplatePart("PART_DayHost", typeof(Panel), IsRequired = true)]
|
|
|
- [TemplatePart("PART_DaySelector", typeof(DateTimePickerPanel), IsRequired = true)]
|
|
|
- [TemplatePart("PART_DayUpButton", typeof(RepeatButton))]
|
|
|
- [TemplatePart("PART_DismissButton", typeof(Button))]
|
|
|
- [TemplatePart("PART_FirstSpacer", typeof(Rectangle))]
|
|
|
- [TemplatePart("PART_MonthDownButton", typeof(RepeatButton))]
|
|
|
- [TemplatePart("PART_MonthHost", typeof(Panel), IsRequired = true)]
|
|
|
- [TemplatePart("PART_MonthSelector", typeof(DateTimePickerPanel), IsRequired = true)]
|
|
|
- [TemplatePart("PART_MonthUpButton", typeof(RepeatButton))]
|
|
|
- [TemplatePart("PART_PickerContainer", typeof(Grid), IsRequired = true)]
|
|
|
- [TemplatePart("PART_SecondSpacer", typeof(Rectangle))]
|
|
|
- [TemplatePart("PART_YearDownButton", typeof(RepeatButton))]
|
|
|
- [TemplatePart("PART_YearHost", typeof(Panel), IsRequired = true)]
|
|
|
- [TemplatePart("PART_YearSelector", typeof(DateTimePickerPanel), IsRequired = true)]
|
|
|
- [TemplatePart("PART_YearUpButton", typeof(RepeatButton))]
|
|
|
+ [TemplatePart(TemplateItems.AcceptButtonName, typeof(Button), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.DayDownButtonName, typeof(Button))]
|
|
|
+ [TemplatePart(TemplateItems.DayHostName, typeof(Panel), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.DaySelectorName, typeof(DateTimePickerPanel), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.DayUpButtonName, typeof(Button))]
|
|
|
+ [TemplatePart(TemplateItems.DismissButtonName, typeof(Button))]
|
|
|
+ [TemplatePart(TemplateItems.FirstSpacerName, typeof(Control))]
|
|
|
+ [TemplatePart(TemplateItems.MonthDownButtonName, typeof(Button))]
|
|
|
+ [TemplatePart(TemplateItems.MonthHostName, typeof(Panel), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.MonthSelectorName, typeof(DateTimePickerPanel), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.MonthUpButtonName, typeof(Button))]
|
|
|
+ [TemplatePart(TemplateItems.PickerContainerName, typeof(Grid), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.SecondSpacerName, typeof(Control))]
|
|
|
+ [TemplatePart(TemplateItems.YearDownButtonName, typeof(Button))]
|
|
|
+ [TemplatePart(TemplateItems.YearHostName, typeof(Panel), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.YearSelectorName, typeof(DateTimePickerPanel), IsRequired = true)]
|
|
|
+ [TemplatePart(TemplateItems.YearUpButtonName, typeof(Button))]
|
|
|
public class DatePickerPresenter : PickerPresenterBase
|
|
|
{
|
|
|
/// <summary>
|
|
|
@@ -102,24 +101,61 @@ namespace Avalonia.Controls
|
|
|
public static readonly StyledProperty<bool> YearVisibleProperty =
|
|
|
DatePicker.YearVisibleProperty.AddOwner<DatePickerPresenter>();
|
|
|
|
|
|
- // 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 struct TemplateItems
|
|
|
+ {
|
|
|
+ public Grid _pickerContainer;
|
|
|
+ public const string PickerContainerName = "PART_PickerContainer";
|
|
|
+
|
|
|
+ public Button _acceptButton;
|
|
|
+ public const string AcceptButtonName = "PART_AcceptButton";
|
|
|
+
|
|
|
+ public Button? _dismissButton;
|
|
|
+ public const string DismissButtonName = "PART_DismissButton";
|
|
|
+
|
|
|
+ public Control? _firstSpacer;
|
|
|
+ public const string FirstSpacerName = "PART_FirstSpacer";
|
|
|
+
|
|
|
+ public Control? _secondSpacer;
|
|
|
+ public const string SecondSpacerName = "PART_SecondSpacer";
|
|
|
+
|
|
|
+ public Panel _monthHost;
|
|
|
+ public const string MonthHostName = "PART_MonthHost";
|
|
|
+
|
|
|
+ public Panel _yearHost;
|
|
|
+ public const string YearHostName = "PART_YearHost";
|
|
|
+
|
|
|
+ public Panel _dayHost;
|
|
|
+ public const string DayHostName = "PART_DayHost";
|
|
|
+
|
|
|
+ public DateTimePickerPanel _monthSelector;
|
|
|
+ public const string MonthSelectorName = "PART_MonthSelector";
|
|
|
+
|
|
|
+ public DateTimePickerPanel _yearSelector;
|
|
|
+ public const string YearSelectorName = "PART_YearSelector";
|
|
|
+
|
|
|
+ public DateTimePickerPanel _daySelector;
|
|
|
+ public const string DaySelectorName = "PART_DaySelector";
|
|
|
+
|
|
|
+ public Button? _monthUpButton;
|
|
|
+ public const string MonthUpButtonName = "PART_MonthUpButton";
|
|
|
+
|
|
|
+ public Button? _dayUpButton;
|
|
|
+ public const string DayUpButtonName = "PART_DayUpButton";
|
|
|
+
|
|
|
+ public Button? _yearUpButton;
|
|
|
+ public const string YearUpButtonName = "PART_YearUpButton";
|
|
|
+
|
|
|
+ public Button? _monthDownButton;
|
|
|
+ public const string MonthDownButtonName = "PART_MonthDownButton";
|
|
|
+
|
|
|
+ public Button? _dayDownButton;
|
|
|
+ public const string DayDownButtonName = "PART_DayDownButton";
|
|
|
+
|
|
|
+ public Button? _yearDownButton;
|
|
|
+ public const string YearDownButtonName = "PART_YearDownButton";
|
|
|
+ }
|
|
|
+
|
|
|
+ private TemplateItems? _templateItems;
|
|
|
|
|
|
private DateTimeOffset _syncDate;
|
|
|
|
|
|
@@ -235,69 +271,54 @@ namespace Avalonia.Controls
|
|
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
|
|
{
|
|
|
base.OnApplyTemplate(e);
|
|
|
- // These are requirements, so throw if not found
|
|
|
- _pickerContainer = e.NameScope.Get<Grid>("PART_PickerContainer");
|
|
|
- _monthHost = e.NameScope.Get<Panel>("PART_MonthHost");
|
|
|
- _dayHost = e.NameScope.Get<Panel>("PART_DayHost");
|
|
|
- _yearHost = e.NameScope.Get<Panel>("PART_YearHost");
|
|
|
|
|
|
- _monthSelector = e.NameScope.Get<DateTimePickerPanel>("PART_MonthSelector");
|
|
|
- _monthSelector.SelectionChanged += OnMonthChanged;
|
|
|
-
|
|
|
- _daySelector = e.NameScope.Get<DateTimePickerPanel>("PART_DaySelector");
|
|
|
- _daySelector.SelectionChanged += OnDayChanged;
|
|
|
-
|
|
|
- _yearSelector = e.NameScope.Get<DateTimePickerPanel>("PART_YearSelector");
|
|
|
- _yearSelector.SelectionChanged += OnYearChanged;
|
|
|
-
|
|
|
- _acceptButton = e.NameScope.Get<Button>("PART_AcceptButton");
|
|
|
-
|
|
|
- _monthUpButton = e.NameScope.Find<RepeatButton>("PART_MonthUpButton");
|
|
|
- if (_monthUpButton != null)
|
|
|
- {
|
|
|
- _monthUpButton.Click += OnSelectorButtonClick;
|
|
|
- }
|
|
|
- _monthDownButton = e.NameScope.Find<RepeatButton>("PART_MonthDownButton");
|
|
|
- if (_monthDownButton != null)
|
|
|
+ _templateItems = new()
|
|
|
{
|
|
|
- _monthDownButton.Click += OnSelectorButtonClick;
|
|
|
- }
|
|
|
+ // These are requirements, so throw if not found
|
|
|
+ _pickerContainer = e.NameScope.Get<Grid>(TemplateItems.PickerContainerName),
|
|
|
+ _monthHost = e.NameScope.Get<Panel>(TemplateItems.MonthHostName),
|
|
|
+ _dayHost = e.NameScope.Get<Panel>(TemplateItems.DayHostName),
|
|
|
+ _yearHost = e.NameScope.Get<Panel>(TemplateItems.YearHostName),
|
|
|
+
|
|
|
+ _monthSelector = e.NameScope.Get<DateTimePickerPanel>(TemplateItems.MonthSelectorName),
|
|
|
+ _daySelector = e.NameScope.Get<DateTimePickerPanel>(TemplateItems.DaySelectorName),
|
|
|
+ _yearSelector = e.NameScope.Get<DateTimePickerPanel>(TemplateItems.YearSelectorName),
|
|
|
+
|
|
|
+ _acceptButton = e.NameScope.Get<Button>(TemplateItems.AcceptButtonName),
|
|
|
+
|
|
|
+ _monthUpButton = SelectorButton(TemplateItems.MonthUpButtonName, DateTimePickerPanelType.Month, SpinDirection.Decrease),
|
|
|
+ _monthDownButton = SelectorButton(TemplateItems.MonthDownButtonName, DateTimePickerPanelType.Month, SpinDirection.Increase),
|
|
|
+ _dayUpButton = SelectorButton(TemplateItems.DayUpButtonName, DateTimePickerPanelType.Day, SpinDirection.Decrease),
|
|
|
+ _dayDownButton = SelectorButton(TemplateItems.DayDownButtonName, DateTimePickerPanelType.Day, SpinDirection.Increase),
|
|
|
+ _yearUpButton = SelectorButton(TemplateItems.YearUpButtonName, DateTimePickerPanelType.Year, SpinDirection.Decrease),
|
|
|
+ _yearDownButton = SelectorButton(TemplateItems.YearDownButtonName, DateTimePickerPanelType.Year, SpinDirection.Increase),
|
|
|
+
|
|
|
+ _dismissButton = e.NameScope.Find<Button>(TemplateItems.DismissButtonName),
|
|
|
+ _firstSpacer = e.NameScope.Find<Control>(TemplateItems.FirstSpacerName),
|
|
|
+ _secondSpacer = e.NameScope.Find<Control>(TemplateItems.SecondSpacerName),
|
|
|
+ };
|
|
|
|
|
|
- _dayUpButton = e.NameScope.Find<RepeatButton>("PART_DayUpButton");
|
|
|
- if (_dayUpButton != null)
|
|
|
- {
|
|
|
- _dayUpButton.Click += OnSelectorButtonClick;
|
|
|
- }
|
|
|
- _dayDownButton = e.NameScope.Find<RepeatButton>("PART_DayDownButton");
|
|
|
- if (_dayDownButton != null)
|
|
|
- {
|
|
|
- _dayDownButton.Click += OnSelectorButtonClick;
|
|
|
- }
|
|
|
+ _templateItems.Value._acceptButton.Click += OnAcceptButtonClicked;
|
|
|
+ _templateItems.Value._monthSelector.SelectionChanged += OnMonthChanged;
|
|
|
+ _templateItems.Value._daySelector.SelectionChanged += OnDayChanged;
|
|
|
+ _templateItems.Value._yearSelector.SelectionChanged += OnYearChanged;
|
|
|
|
|
|
- _yearUpButton = e.NameScope.Find<RepeatButton>("PART_YearUpButton");
|
|
|
- if (_yearUpButton != null)
|
|
|
+ if (_templateItems.Value._dismissButton is { } dismissButton)
|
|
|
{
|
|
|
- _yearUpButton.Click += OnSelectorButtonClick;
|
|
|
- }
|
|
|
- _yearDownButton = e.NameScope.Find<RepeatButton>("PART_YearDownButton");
|
|
|
- if (_yearDownButton != null)
|
|
|
- {
|
|
|
- _yearDownButton.Click += OnSelectorButtonClick;
|
|
|
+ dismissButton.Click += OnDismissButtonClicked;
|
|
|
}
|
|
|
|
|
|
- _dismissButton = e.NameScope.Find<Button>("PART_DismissButton");
|
|
|
- _spacer1 = e.NameScope.Find<Rectangle>("PART_FirstSpacer");
|
|
|
- _spacer2 = e.NameScope.Find<Rectangle>("PART_SecondSpacer");
|
|
|
+ InitPicker();
|
|
|
|
|
|
- if (_acceptButton != null)
|
|
|
- {
|
|
|
- _acceptButton.Click += OnAcceptButtonClicked;
|
|
|
- }
|
|
|
- if (_dismissButton != null)
|
|
|
+ Button? SelectorButton(string name, DateTimePickerPanelType type, SpinDirection direction)
|
|
|
{
|
|
|
- _dismissButton.Click += OnDismissButtonClicked;
|
|
|
+ if (e.NameScope.Find<Button>(name) is { } button)
|
|
|
+ {
|
|
|
+ button.Click += (s, e) => OnSelectorButtonClick(type, direction);
|
|
|
+ return button;
|
|
|
+ }
|
|
|
+ return null;
|
|
|
}
|
|
|
- InitPicker();
|
|
|
}
|
|
|
|
|
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
|
|
@@ -350,63 +371,63 @@ namespace Avalonia.Controls
|
|
|
private void InitPicker()
|
|
|
{
|
|
|
// OnApplyTemplate must've been called before we can init here...
|
|
|
- if (_pickerContainer == null)
|
|
|
+ if (_templateItems is not { } items)
|
|
|
return;
|
|
|
|
|
|
_suppressUpdateSelection = true;
|
|
|
|
|
|
- _monthSelector!.MaximumValue = 12;
|
|
|
- _monthSelector.MinimumValue = 1;
|
|
|
- _monthSelector.ItemFormat = MonthFormat;
|
|
|
+ items._monthSelector.MaximumValue = 12;
|
|
|
+ items._monthSelector.MinimumValue = 1;
|
|
|
+ items._monthSelector.ItemFormat = MonthFormat;
|
|
|
|
|
|
- _daySelector!.ItemFormat = DayFormat;
|
|
|
+ items._daySelector.ItemFormat = DayFormat;
|
|
|
|
|
|
- _yearSelector!.MaximumValue = MaxYear.Year;
|
|
|
- _yearSelector.MinimumValue = MinYear.Year;
|
|
|
- _yearSelector.ItemFormat = YearFormat;
|
|
|
+ items._yearSelector.MaximumValue = MaxYear.Year;
|
|
|
+ items._yearSelector.MinimumValue = MinYear.Year;
|
|
|
+ items._yearSelector.ItemFormat = YearFormat;
|
|
|
|
|
|
- SetGrid();
|
|
|
+ SetGrid(items);
|
|
|
|
|
|
// Date should've been set when we reach this point
|
|
|
var dt = Date;
|
|
|
if (DayVisible)
|
|
|
{
|
|
|
- _daySelector.FormatDate = dt.Date;
|
|
|
+ items._daySelector.FormatDate = dt.Date;
|
|
|
var maxDays = _calendar.GetDaysInMonth(dt.Year, dt.Month);
|
|
|
- _daySelector.MaximumValue = maxDays;
|
|
|
- _daySelector.MinimumValue = 1;
|
|
|
- _daySelector.SelectedValue = dt.Day;
|
|
|
+ items._daySelector.MaximumValue = maxDays;
|
|
|
+ items._daySelector.MinimumValue = 1;
|
|
|
+ items._daySelector.SelectedValue = dt.Day;
|
|
|
}
|
|
|
|
|
|
if (MonthVisible)
|
|
|
{
|
|
|
- _monthSelector.SelectedValue = dt.Month;
|
|
|
- _monthSelector.FormatDate = dt.Date;
|
|
|
+ items._monthSelector.SelectedValue = dt.Month;
|
|
|
+ items._monthSelector.FormatDate = dt.Date;
|
|
|
}
|
|
|
|
|
|
if (YearVisible)
|
|
|
{
|
|
|
- _yearSelector.SelectedValue = dt.Year;
|
|
|
- _yearSelector.FormatDate = dt.Date;
|
|
|
+ items._yearSelector.SelectedValue = dt.Year;
|
|
|
+ items._yearSelector.FormatDate = dt.Date;
|
|
|
}
|
|
|
|
|
|
_suppressUpdateSelection = false;
|
|
|
|
|
|
- SetInitialFocus();
|
|
|
+ SetInitialFocus(items);
|
|
|
}
|
|
|
|
|
|
- private void SetGrid()
|
|
|
+ private void SetGrid(TemplateItems items)
|
|
|
{
|
|
|
var fmt = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
|
|
|
var columns = new List<(Panel?, int)>
|
|
|
{
|
|
|
- (_monthHost, MonthVisible ? fmt.IndexOf("m", StringComparison.OrdinalIgnoreCase) : -1),
|
|
|
- (_yearHost, YearVisible ? fmt.IndexOf("y", StringComparison.OrdinalIgnoreCase) : -1),
|
|
|
- (_dayHost, DayVisible ? fmt.IndexOf("d", StringComparison.OrdinalIgnoreCase) : -1),
|
|
|
+ (items._monthHost, MonthVisible ? fmt.IndexOf("m", StringComparison.OrdinalIgnoreCase) : -1),
|
|
|
+ (items._yearHost, YearVisible ? fmt.IndexOf("y", StringComparison.OrdinalIgnoreCase) : -1),
|
|
|
+ (items._dayHost, DayVisible ? fmt.IndexOf("d", StringComparison.OrdinalIgnoreCase) : -1),
|
|
|
};
|
|
|
|
|
|
columns.Sort((x, y) => x.Item2 - y.Item2);
|
|
|
- _pickerContainer!.ColumnDefinitions.Clear();
|
|
|
+ items._pickerContainer.ColumnDefinitions.Clear();
|
|
|
|
|
|
var columnIndex = 0;
|
|
|
|
|
|
@@ -421,48 +442,53 @@ namespace Avalonia.Controls
|
|
|
{
|
|
|
if (columnIndex > 0)
|
|
|
{
|
|
|
- _pickerContainer.ColumnDefinitions.Add(new ColumnDefinition(0, GridUnitType.Auto));
|
|
|
+ items._pickerContainer.ColumnDefinitions.Add(new ColumnDefinition(0, GridUnitType.Auto));
|
|
|
}
|
|
|
|
|
|
- _pickerContainer.ColumnDefinitions.Add(
|
|
|
- new ColumnDefinition(column.Item1 == _monthHost ? 138 : 78, GridUnitType.Star));
|
|
|
+ items._pickerContainer.ColumnDefinitions.Add(
|
|
|
+ new ColumnDefinition(column.Item1 == items._monthHost ? 138 : 78, GridUnitType.Star));
|
|
|
|
|
|
if (column.Item1.Parent is null)
|
|
|
{
|
|
|
- _pickerContainer.Children.Add(column.Item1);
|
|
|
+ items._pickerContainer.Children.Add(column.Item1);
|
|
|
}
|
|
|
|
|
|
Grid.SetColumn(column.Item1, (columnIndex++ * 2));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- var isSpacer1Visible = columnIndex > 1;
|
|
|
- var isSpacer2Visible = columnIndex > 2;
|
|
|
- // ternary conditional operator is used to make sure grid cells will be validated
|
|
|
- Grid.SetColumn(_spacer1!, isSpacer1Visible ? 1 : 0);
|
|
|
- Grid.SetColumn(_spacer2!, isSpacer2Visible ? 3 : 0);
|
|
|
+ ConfigureSpacer(items._firstSpacer, columnIndex > 1);
|
|
|
+ ConfigureSpacer(items._secondSpacer, columnIndex > 2);
|
|
|
+
|
|
|
+ static void ConfigureSpacer(Control? spacer, bool visible)
|
|
|
+ {
|
|
|
+ if (spacer == null)
|
|
|
+ return;
|
|
|
+
|
|
|
+ // ternary conditional operator is used to make sure grid cells will be validated
|
|
|
+ Grid.SetColumn(spacer, visible ? 1 : 0);
|
|
|
+ spacer.IsVisible = visible;
|
|
|
|
|
|
- _spacer1!.IsVisible = isSpacer1Visible;
|
|
|
- _spacer2!.IsVisible = isSpacer2Visible;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- private void SetInitialFocus()
|
|
|
+ private void SetInitialFocus(TemplateItems items)
|
|
|
{
|
|
|
- int monthCol = MonthVisible ? Grid.GetColumn(_monthHost!) : int.MaxValue;
|
|
|
- int dayCol = DayVisible ? Grid.GetColumn(_dayHost!) : int.MaxValue;
|
|
|
- int yearCol = YearVisible ? Grid.GetColumn(_yearHost!) : int.MaxValue;
|
|
|
+ int monthCol = MonthVisible ? Grid.GetColumn(items._monthHost) : int.MaxValue;
|
|
|
+ int dayCol = DayVisible ? Grid.GetColumn(items._dayHost) : int.MaxValue;
|
|
|
+ int yearCol = YearVisible ? Grid.GetColumn(items._yearHost) : int.MaxValue;
|
|
|
|
|
|
if (monthCol < dayCol && monthCol < yearCol)
|
|
|
{
|
|
|
- _monthSelector?.Focus(NavigationMethod.Pointer);
|
|
|
+ items._monthSelector.Focus(NavigationMethod.Pointer);
|
|
|
}
|
|
|
else if (dayCol < monthCol && dayCol < yearCol)
|
|
|
{
|
|
|
- _monthSelector?.Focus(NavigationMethod.Pointer);
|
|
|
+ items._monthSelector.Focus(NavigationMethod.Pointer);
|
|
|
}
|
|
|
else if (yearCol < monthCol && yearCol < dayCol)
|
|
|
{
|
|
|
- _yearSelector?.Focus(NavigationMethod.Pointer);
|
|
|
+ items._yearSelector.Focus(NavigationMethod.Pointer);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -477,29 +503,36 @@ namespace Avalonia.Controls
|
|
|
OnConfirmed();
|
|
|
}
|
|
|
|
|
|
- private void OnSelectorButtonClick(object? sender, RoutedEventArgs e)
|
|
|
+ private void OnSelectorButtonClick(DateTimePickerPanelType type, SpinDirection direction)
|
|
|
{
|
|
|
- if (sender == _monthUpButton)
|
|
|
- _monthSelector!.ScrollUp();
|
|
|
- else if (sender == _monthDownButton)
|
|
|
- _monthSelector!.ScrollDown();
|
|
|
- else if (sender == _yearUpButton)
|
|
|
- _yearSelector!.ScrollUp();
|
|
|
- else if (sender == _yearDownButton)
|
|
|
- _yearSelector!.ScrollDown();
|
|
|
- else if (sender == _dayUpButton)
|
|
|
- _daySelector!.ScrollUp();
|
|
|
- else if (sender == _dayDownButton)
|
|
|
- _daySelector!.ScrollDown();
|
|
|
+ var target = type switch
|
|
|
+ {
|
|
|
+ DateTimePickerPanelType.Month => _templateItems?._monthSelector,
|
|
|
+ DateTimePickerPanelType.Day => _templateItems?._daySelector,
|
|
|
+ DateTimePickerPanelType.Year=> _templateItems?._yearSelector,
|
|
|
+ _ => throw new NotImplementedException(),
|
|
|
+ };
|
|
|
+
|
|
|
+ switch (direction)
|
|
|
+ {
|
|
|
+ case SpinDirection.Increase:
|
|
|
+ target?.ScrollDown();
|
|
|
+ break;
|
|
|
+ case SpinDirection.Decrease:
|
|
|
+ target?.ScrollUp();
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new NotImplementedException();
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
private void OnYearChanged(object? sender, EventArgs e)
|
|
|
{
|
|
|
- if (_suppressUpdateSelection)
|
|
|
+ if (_suppressUpdateSelection || _templateItems is not { } items)
|
|
|
return;
|
|
|
|
|
|
- int maxDays = _calendar.GetDaysInMonth(_yearSelector!.SelectedValue, _syncDate.Month);
|
|
|
- var newDate = new DateTimeOffset(_yearSelector.SelectedValue, _syncDate.Month,
|
|
|
+ int maxDays = _calendar.GetDaysInMonth(items._yearSelector.SelectedValue, _syncDate.Month);
|
|
|
+ var newDate = new DateTimeOffset(items._yearSelector.SelectedValue, _syncDate.Month,
|
|
|
_syncDate.Day > maxDays ? maxDays : _syncDate.Day, 0, 0, 0, _syncDate.Offset);
|
|
|
|
|
|
_syncDate = newDate;
|
|
|
@@ -510,30 +543,30 @@ namespace Avalonia.Controls
|
|
|
|
|
|
_suppressUpdateSelection = true;
|
|
|
|
|
|
- _daySelector!.FormatDate = newDate.Date;
|
|
|
+ items._daySelector.FormatDate = newDate.Date;
|
|
|
|
|
|
- if (_daySelector.MaximumValue != maxDays)
|
|
|
- _daySelector.MaximumValue = maxDays;
|
|
|
+ if (items._daySelector.MaximumValue != maxDays)
|
|
|
+ items._daySelector.MaximumValue = maxDays;
|
|
|
else
|
|
|
- _daySelector.RefreshItems();
|
|
|
+ items._daySelector.RefreshItems();
|
|
|
|
|
|
_suppressUpdateSelection = false;
|
|
|
}
|
|
|
|
|
|
private void OnDayChanged(object? sender, EventArgs e)
|
|
|
{
|
|
|
- if (_suppressUpdateSelection)
|
|
|
+ if (_suppressUpdateSelection || _templateItems is not { } items)
|
|
|
return;
|
|
|
- _syncDate = new DateTimeOffset(_syncDate.Year, _syncDate.Month, _daySelector!.SelectedValue, 0, 0, 0, _syncDate.Offset);
|
|
|
+ _syncDate = new DateTimeOffset(_syncDate.Year, _syncDate.Month, items._daySelector.SelectedValue, 0, 0, 0, _syncDate.Offset);
|
|
|
}
|
|
|
|
|
|
private void OnMonthChanged(object? sender, EventArgs e)
|
|
|
{
|
|
|
- if (_suppressUpdateSelection)
|
|
|
+ if (_suppressUpdateSelection || _templateItems is not { } items)
|
|
|
return;
|
|
|
|
|
|
- int maxDays = _calendar.GetDaysInMonth(_syncDate.Year, _monthSelector!.SelectedValue);
|
|
|
- var newDate = new DateTimeOffset(_syncDate.Year, _monthSelector.SelectedValue,
|
|
|
+ int maxDays = _calendar.GetDaysInMonth(_syncDate.Year, items._monthSelector.SelectedValue);
|
|
|
+ var newDate = new DateTimeOffset(_syncDate.Year, items._monthSelector.SelectedValue,
|
|
|
_syncDate.Day > maxDays ? maxDays : _syncDate.Day, 0, 0, 0, _syncDate.Offset);
|
|
|
|
|
|
if (!DayVisible)
|
|
|
@@ -544,24 +577,24 @@ namespace Avalonia.Controls
|
|
|
|
|
|
_suppressUpdateSelection = true;
|
|
|
|
|
|
- _daySelector!.FormatDate = newDate.Date;
|
|
|
+ items._daySelector.FormatDate = newDate.Date;
|
|
|
_syncDate = newDate;
|
|
|
|
|
|
- if (_daySelector.MaximumValue != maxDays)
|
|
|
- _daySelector.MaximumValue = maxDays;
|
|
|
+ if (items._daySelector.MaximumValue != maxDays)
|
|
|
+ items._daySelector.MaximumValue = maxDays;
|
|
|
else
|
|
|
- _daySelector.RefreshItems();
|
|
|
+ items._daySelector.RefreshItems();
|
|
|
|
|
|
_suppressUpdateSelection = false;
|
|
|
}
|
|
|
|
|
|
internal double GetOffsetForPopup()
|
|
|
{
|
|
|
- if (_monthSelector is null)
|
|
|
+ if (_templateItems is not { } items)
|
|
|
return 0;
|
|
|
|
|
|
- var acceptDismissButtonHeight = _acceptButton != null ? _acceptButton.Bounds.Height : 41;
|
|
|
- return -(MaxHeight - acceptDismissButtonHeight) / 2 - (_monthSelector.ItemHeight / 2);
|
|
|
+ var acceptDismissButtonHeight = items._acceptButton.Bounds.Height;
|
|
|
+ return -(MaxHeight - acceptDismissButtonHeight) / 2 - (items._monthSelector.ItemHeight / 2);
|
|
|
}
|
|
|
}
|
|
|
}
|