using System.Globalization; using System.Runtime.CompilerServices; using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Primitives; using Avalonia.Data; using Avalonia.Input; using Avalonia.Interactivity; using Irihi.Avalonia.Shared.Helpers; namespace Ursa.Controls; [TemplatePart(PART_Button, typeof(Button))] [TemplatePart(PART_Popup, typeof(Popup))] [TemplatePart(PART_TextBox, typeof(TextBox))] [TemplatePart(PART_Calendar, typeof(CalendarView))] [TemplatePart(PART_TimePicker, typeof(TimePicker))] public class DateTimePicker : DatePickerBase { public const string PART_Button = "PART_Button"; public const string PART_Popup = "PART_Popup"; public const string PART_TextBox = "PART_TextBox"; public const string PART_Calendar = "PART_Calendar"; public const string PART_TimePicker = "PART_TimePicker"; public static readonly StyledProperty SelectedDateProperty = AvaloniaProperty.Register( nameof(SelectedDate), defaultBindingMode: BindingMode.TwoWay); public static readonly StyledProperty WatermarkProperty = AvaloniaProperty.Register( nameof(Watermark)); public static readonly StyledProperty PanelFormatProperty = AvaloniaProperty.Register( nameof(PanelFormat), "HH mm ss"); public static readonly StyledProperty NeedConfirmationProperty = AvaloniaProperty.Register( nameof(NeedConfirmation)); private Button? _button; private CalendarView? _calendar; private TextBox? _textBox; private TimePickerPresenter? _timePickerPresenter; static DateTimePicker() { DisplayFormatProperty.OverrideDefaultValue(CultureInfo.InvariantCulture.DateTimeFormat.FullDateTimePattern); SelectedDateProperty.Changed.AddClassHandler((picker, args) => picker.OnSelectionChanged(args)); } public DateTime? SelectedDate { get => GetValue(SelectedDateProperty); set => SetValue(SelectedDateProperty, value); } public string? Watermark { get => GetValue(WatermarkProperty); set => SetValue(WatermarkProperty, value); } public string PanelFormat { get => GetValue(PanelFormatProperty); set => SetValue(PanelFormatProperty, value); } public bool NeedConfirmation { get => GetValue(NeedConfirmationProperty); set => SetValue(NeedConfirmationProperty, value); } private void OnSelectionChanged(AvaloniaPropertyChangedEventArgs args) { SyncSelectedDateToText(args.NewValue.Value); } private void SyncSelectedDateToText(DateTime? date) { if (date is null) { _textBox?.SetValue(TextBox.TextProperty, null); _calendar?.ClearSelection(); _timePickerPresenter?.SetValue(TimePickerPresenter.TimeProperty, null); } else { _textBox?.SetValue(TextBox.TextProperty, date.Value.ToString(DisplayFormat ?? CultureInfo.InvariantCulture.DateTimeFormat.FullDateTimePattern)); _calendar?.MarkDates(date.Value.Date, date.Value.Date); _timePickerPresenter?.SetValue(TimePickerPresenter.TimeProperty, date.Value.TimeOfDay); } } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); GotFocusEvent.RemoveHandler(OnTextBoxGetFocus, _textBox); TextBox.TextChangedEvent.RemoveHandler(OnTextChanged, _textBox); PointerPressedEvent.RemoveHandler(OnTextBoxPointerPressed, _textBox); Button.ClickEvent.RemoveHandler(OnButtonClick, _button); CalendarView.DateSelectedEvent.RemoveHandler(OnDateSelected, _calendar); TimePickerPresenter.SelectedTimeChangedEvent.RemoveHandler(OnTimeSelectedChanged, _timePickerPresenter); _button = e.NameScope.Find