From e5f1f550e4252467ef26e1ba712da60b356d0a17 Mon Sep 17 00:00:00 2001 From: chinboy Date: Fri, 15 Aug 2025 14:47:51 +0800 Subject: [PATCH] Fix DatePicker Arrow bug --- src/AtomUI.Controls/DatePicker/DatePicker.cs | 32 +++------ .../DatePicker/DatePickerFlyout.cs | 71 +++++++++++++++++-- .../DatePicker/DatePickerFlyoutPresenter.cs | 18 ----- .../DatePicker/RangeDatePicker.cs | 34 +++------ .../DatePicker/RangeDatePickerFlyout.cs | 62 ++++++++++++++-- .../RangeDatePickerFlyoutPresenter.cs | 57 --------------- .../DatePickerFlyoutPresenterTheme.axaml | 42 ----------- .../DatePicker/Themes/DatePickerThemes.axaml | 2 - .../RangeDatePickerFlyoutPresenterTheme.axaml | 41 ----------- 9 files changed, 143 insertions(+), 216 deletions(-) delete mode 100644 src/AtomUI.Controls/DatePicker/DatePickerFlyoutPresenter.cs delete mode 100644 src/AtomUI.Controls/DatePicker/RangeDatePickerFlyoutPresenter.cs delete mode 100644 src/AtomUI.Controls/DatePicker/Themes/DatePickerFlyoutPresenterTheme.axaml delete mode 100644 src/AtomUI.Controls/DatePicker/Themes/RangeDatePickerFlyoutPresenterTheme.axaml diff --git a/src/AtomUI.Controls/DatePicker/DatePicker.cs b/src/AtomUI.Controls/DatePicker/DatePicker.cs index 1d28c53fb..cb1f69889 100644 --- a/src/AtomUI.Controls/DatePicker/DatePicker.cs +++ b/src/AtomUI.Controls/DatePicker/DatePicker.cs @@ -165,36 +165,24 @@ public class DatePicker : InfoPickerInput, var flyout = new DatePickerFlyout(); flyout.IsDetectMouseClickEnabled = false; BindUtils.RelayBind(this, IsMotionEnabledProperty, flyout, DatePickerFlyout.IsMotionEnabledProperty); + BindUtils.RelayBind(this, IsMotionEnabledProperty, flyout, DatePickerPresenter.IsMotionEnabledProperty); + BindUtils.RelayBind(this, SelectedDateTimeProperty, flyout, DatePickerPresenter.SelectedDateTimeProperty); + BindUtils.RelayBind(this, IsNeedConfirmProperty, flyout, DatePickerPresenter.IsNeedConfirmProperty); + BindUtils.RelayBind(this, IsShowNowProperty, flyout, DatePickerPresenter.IsShowNowProperty); + BindUtils.RelayBind(this, IsShowTimeProperty, flyout, DatePickerPresenter.IsShowTimeProperty); + BindUtils.RelayBind(this, ClockIdentifierProperty, flyout, DatePickerPresenter.ClockIdentifierProperty); + return flyout; } protected override void NotifyFlyoutPresenterCreated(Control flyoutPresenter) { - if (flyoutPresenter is DatePickerFlyoutPresenter datePickerFlyoutPresenter) + if (PickerFlyout is DatePickerFlyout datePickerFlyout) { - datePickerFlyoutPresenter.AttachedToVisualTree += (sender, args) => - { - _pickerPresenter = datePickerFlyoutPresenter.DatePickerPresenter; - ConfigurePickerPresenter(_pickerPresenter); - }; + _pickerPresenter = datePickerFlyout.DatePickerPresenter; } } - - private void ConfigurePickerPresenter(DatePickerPresenter? presenter) - { - if (presenter is null) - { - return; - } - - BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, DatePickerPresenter.IsMotionEnabledProperty); - BindUtils.RelayBind(this, SelectedDateTimeProperty, presenter, DatePickerPresenter.SelectedDateTimeProperty); - BindUtils.RelayBind(this, IsNeedConfirmProperty, presenter, DatePickerPresenter.IsNeedConfirmProperty); - BindUtils.RelayBind(this, IsShowNowProperty, presenter, DatePickerPresenter.IsShowNowProperty); - BindUtils.RelayBind(this, IsShowTimeProperty, presenter, DatePickerPresenter.IsShowTimeProperty); - BindUtils.RelayBind(this, ClockIdentifierProperty, presenter, DatePickerPresenter.ClockIdentifierProperty); - } - + protected override void NotifyFlyoutOpened() { base.NotifyFlyoutOpened(); diff --git a/src/AtomUI.Controls/DatePicker/DatePickerFlyout.cs b/src/AtomUI.Controls/DatePicker/DatePickerFlyout.cs index 4df4181f5..f16375d4d 100644 --- a/src/AtomUI.Controls/DatePicker/DatePickerFlyout.cs +++ b/src/AtomUI.Controls/DatePicker/DatePickerFlyout.cs @@ -1,18 +1,77 @@ using AtomUI.Data; +using Avalonia; using Avalonia.Controls; namespace AtomUI.Controls; internal class DatePickerFlyout : Flyout { + public static readonly StyledProperty SelectedDateTimeProperty = + DatePicker.SelectedDateTimeProperty.AddOwner(); + + public static readonly StyledProperty IsNeedConfirmProperty = + DatePicker.IsNeedConfirmProperty.AddOwner(); + + public static readonly StyledProperty IsShowNowProperty = + DatePicker.IsShowNowProperty.AddOwner(); + + public static readonly StyledProperty IsShowTimeProperty = + DatePicker.IsShowTimeProperty.AddOwner(); + + public static readonly StyledProperty ClockIdentifierProperty = + TimePicker.ClockIdentifierProperty.AddOwner(); + + public DateTime? SelectedDateTime + { + get => GetValue(SelectedDateTimeProperty); + set => SetValue(SelectedDateTimeProperty, value); + } + + public bool IsNeedConfirm + { + get => GetValue(IsNeedConfirmProperty); + set => SetValue(IsNeedConfirmProperty, value); + } + + public bool IsShowNow + { + get => GetValue(IsShowNowProperty); + set => SetValue(IsShowNowProperty, value); + } + + public bool IsShowTime + { + get => GetValue(IsShowTimeProperty); + set => SetValue(IsShowTimeProperty, value); + } + + public ClockIdentifierType ClockIdentifier + { + get => GetValue(ClockIdentifierProperty); + set => SetValue(ClockIdentifierProperty, value); + } + + internal DatePickerPresenter? DatePickerPresenter { get; set; } + protected override Control CreatePresenter() { - var presenter = new DatePickerFlyoutPresenter(); - - BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, presenter, IsShowArrowProperty); - + DatePickerPresenter = new DatePickerPresenter(); + + BindUtils.RelayBind(this, IsMotionEnabledProperty, DatePickerPresenter, DatePickerPresenter.IsMotionEnabledProperty); + BindUtils.RelayBind(this, SelectedDateTimeProperty, DatePickerPresenter, DatePickerPresenter.SelectedDateTimeProperty); + BindUtils.RelayBind(this, IsNeedConfirmProperty, DatePickerPresenter, DatePickerPresenter.IsNeedConfirmProperty); + BindUtils.RelayBind(this, IsShowNowProperty, DatePickerPresenter, DatePickerPresenter.IsShowNowProperty); + BindUtils.RelayBind(this, IsShowTimeProperty, DatePickerPresenter, DatePickerPresenter.IsShowTimeProperty); + BindUtils.RelayBind(this, ClockIdentifierProperty, DatePickerPresenter, DatePickerPresenter.ClockIdentifierProperty); + + var flyoutPresenter = new FlyoutPresenter + { + Content = DatePickerPresenter + }; + BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, flyoutPresenter, IsShowArrowProperty); + CalculateShowArrowEffective(); - SetupArrowPosition(Popup, presenter); - return presenter; + SetupArrowPosition(Popup, flyoutPresenter); + return flyoutPresenter; } } \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/DatePickerFlyoutPresenter.cs b/src/AtomUI.Controls/DatePicker/DatePickerFlyoutPresenter.cs deleted file mode 100644 index e2ab855b1..000000000 --- a/src/AtomUI.Controls/DatePicker/DatePickerFlyoutPresenter.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AtomUI.Controls.Themes; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; - -namespace AtomUI.Controls; - -internal class DatePickerFlyoutPresenter : FlyoutPresenter -{ - protected override Type StyleKeyOverride => typeof(DatePickerFlyoutPresenter); - - internal DatePickerPresenter? DatePickerPresenter; - - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - DatePickerPresenter = e.NameScope.Get(DatePickerFlyoutPresenterThemeConstants.DatePickerPresenterPart); - } -} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/RangeDatePicker.cs b/src/AtomUI.Controls/DatePicker/RangeDatePicker.cs index 6f9cc287c..cd8043072 100644 --- a/src/AtomUI.Controls/DatePicker/RangeDatePicker.cs +++ b/src/AtomUI.Controls/DatePicker/RangeDatePicker.cs @@ -128,6 +128,14 @@ public class RangeDatePicker : RangeInfoPickerInput, var flyout = new RangeDatePickerFlyout(); flyout.IsDetectMouseClickEnabled = false; BindUtils.RelayBind(this, IsMotionEnabledProperty, flyout, RangeDatePickerFlyout.IsMotionEnabledProperty); + + BindUtils.RelayBind(this, RangeStartSelectedDateProperty, flyout, RangeDatePickerFlyout.SelectedDateTimeProperty); + BindUtils.RelayBind(this, RangeEndSelectedDateProperty, flyout, RangeDatePickerFlyout.SecondarySelectedDateTimeProperty); + BindUtils.RelayBind(this, ClockIdentifierProperty, flyout, RangeDatePickerFlyout.ClockIdentifierProperty); + BindUtils.RelayBind(this, IsNeedConfirmProperty, flyout, RangeDatePickerFlyout.IsNeedConfirmProperty); + BindUtils.RelayBind(this, IsShowNowProperty, flyout, RangeDatePickerFlyout.IsShowNowProperty); + BindUtils.RelayBind(this, IsShowTimeProperty, flyout, RangeDatePickerFlyout.IsShowTimeProperty); + return flyout; } @@ -147,32 +155,13 @@ public class RangeDatePicker : RangeInfoPickerInput, protected override void NotifyFlyoutPresenterCreated(Control flyoutPresenter) { - if (flyoutPresenter is RangeDatePickerFlyoutPresenter rangeDatePickerFlyoutPresenter) + if (PickerFlyout is RangeDatePickerFlyout datePickerFlyout) { - BindUtils.RelayBind(this, IsShowTimeProperty, rangeDatePickerFlyoutPresenter, RangeDatePickerFlyoutPresenter.IsShowTimeProperty); - rangeDatePickerFlyoutPresenter.AttachedToVisualTree += (sender, args) => - { - _pickerPresenter = rangeDatePickerFlyoutPresenter.DatePickerPresenter; - ConfigurePickerPresenter(_pickerPresenter); - }; + _pickerPresenter = datePickerFlyout.DatePickerPresenter as RangeDatePickerPresenter; + _pickerPresenter?.NotifyRepairReverseRange(true); } } - private void ConfigurePickerPresenter(RangeDatePickerPresenter? presenter) - { - if (presenter is null) - { - return; - } - presenter.NotifyRepairReverseRange(true); - BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, RangeDatePickerPresenter.IsMotionEnabledProperty); - BindUtils.RelayBind(this, RangeStartSelectedDateProperty, presenter, RangeDatePickerPresenter.SelectedDateTimeProperty); - BindUtils.RelayBind(this, RangeEndSelectedDateProperty, presenter, RangeDatePickerPresenter.SecondarySelectedDateTimeProperty); - BindUtils.RelayBind(this, ClockIdentifierProperty, presenter, RangeDatePickerPresenter.ClockIdentifierProperty); - BindUtils.RelayBind(this, IsNeedConfirmProperty, presenter, RangeDatePickerPresenter.IsNeedConfirmProperty); - BindUtils.RelayBind(this, IsShowNowProperty, presenter, RangeDatePickerPresenter.IsShowNowProperty); - } - protected override void NotifyFlyoutOpened() { base.NotifyFlyoutOpened(); @@ -193,7 +182,6 @@ public class RangeDatePicker : RangeInfoPickerInput, { _pickerPresenter.NotifySelectRangeStart(false); } - } } diff --git a/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyout.cs b/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyout.cs index 0acfe8875..807dee2bf 100644 --- a/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyout.cs +++ b/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyout.cs @@ -1,16 +1,68 @@ using AtomUI.Data; +using Avalonia; using Avalonia.Controls; namespace AtomUI.Controls; -internal class RangeDatePickerFlyout : Flyout +internal class RangeDatePickerFlyout : DatePickerFlyout { + public static readonly StyledProperty SecondarySelectedDateTimeProperty = + RangeDatePickerPresenter.SecondarySelectedDateTimeProperty.AddOwner(); + + public DateTime? SecondarySelectedDateTime + { + get => GetValue(SecondarySelectedDateTimeProperty); + set => SetValue(SecondarySelectedDateTimeProperty, value); + } + + internal FlyoutPresenter? _flyoutPresenter; + protected override Control CreatePresenter() { - var presenter = new RangeDatePickerFlyoutPresenter(); - BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, presenter, IsShowArrowProperty); + _flyoutPresenter = new FlyoutPresenter(); + ConfigureDatePickerPresenter(); + BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, _flyoutPresenter, IsShowArrowProperty); CalculateShowArrowEffective(); - SetupArrowPosition(Popup, presenter); - return presenter; + SetupArrowPosition(Popup, _flyoutPresenter); + return _flyoutPresenter; + } + + private void ConfigureDatePickerPresenter() + { + if (_flyoutPresenter != null) + { + DatePickerPresenter? presenter; + if (IsShowTime) + { + presenter = new TimedRangeDatePickerPresenter() + { + IsShowTime = true + }; + } + else + { + presenter = new DualMonthRangeDatePickerPresenter(); + } + + BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, RangeDatePickerPresenter.IsMotionEnabledProperty); + BindUtils.RelayBind(this, SelectedDateTimeProperty, presenter, RangeDatePickerPresenter.SelectedDateTimeProperty); + BindUtils.RelayBind(this, IsNeedConfirmProperty, presenter, RangeDatePickerPresenter.IsNeedConfirmProperty); + BindUtils.RelayBind(this, IsShowNowProperty, presenter, RangeDatePickerPresenter.IsShowNowProperty); + BindUtils.RelayBind(this, IsShowTimeProperty, presenter, RangeDatePickerPresenter.IsShowTimeProperty); + BindUtils.RelayBind(this, ClockIdentifierProperty, presenter, RangeDatePickerPresenter.ClockIdentifierProperty); + BindUtils.RelayBind(this, SecondarySelectedDateTimeProperty, presenter, RangeDatePickerPresenter.SecondarySelectedDateTimeProperty); + + _flyoutPresenter.Content = presenter; + DatePickerPresenter = presenter; + } + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) + { + base.OnPropertyChanged(e); + if (e.Property == IsShowTimeProperty) + { + ConfigureDatePickerPresenter(); + } } } \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyoutPresenter.cs b/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyoutPresenter.cs deleted file mode 100644 index 637bc955e..000000000 --- a/src/AtomUI.Controls/DatePicker/RangeDatePickerFlyoutPresenter.cs +++ /dev/null @@ -1,57 +0,0 @@ -using AtomUI.Data; -using Avalonia; -using Avalonia.Controls.Primitives; - -namespace AtomUI.Controls; - -internal class RangeDatePickerFlyoutPresenter : FlyoutPresenter -{ - #region 公共属性定义 - - public static readonly StyledProperty IsShowTimeProperty = - DatePicker.IsShowTimeProperty.AddOwner(); - - public bool IsShowTime - { - get => GetValue(IsShowTimeProperty); - set => SetValue(IsShowTimeProperty, value); - } - - #endregion - - internal RangeDatePickerPresenter? DatePickerPresenter; - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - SetupDatePickerPresenter(); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) - { - base.OnPropertyChanged(e); - if (e.Property == IsShowTimeProperty) - { - SetupDatePickerPresenter(); - } - } - - private void SetupDatePickerPresenter() - { - if (IsShowTime) - { - DatePickerPresenter = new TimedRangeDatePickerPresenter() - { - IsShowTime = true - }; - } - else - { - DatePickerPresenter = new DualMonthRangeDatePickerPresenter(); - } - - BindUtils.RelayBind(this, IsMotionEnabledProperty, DatePickerPresenter, IsMotionEnabledProperty); - - Content = DatePickerPresenter; - } -} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/Themes/DatePickerFlyoutPresenterTheme.axaml b/src/AtomUI.Controls/DatePicker/Themes/DatePickerFlyoutPresenterTheme.axaml deleted file mode 100644 index dc252b1bf..000000000 --- a/src/AtomUI.Controls/DatePicker/Themes/DatePickerFlyoutPresenterTheme.axaml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/Themes/DatePickerThemes.axaml b/src/AtomUI.Controls/DatePicker/Themes/DatePickerThemes.axaml index e4904d170..ca50416ff 100644 --- a/src/AtomUI.Controls/DatePicker/Themes/DatePickerThemes.axaml +++ b/src/AtomUI.Controls/DatePicker/Themes/DatePickerThemes.axaml @@ -11,9 +11,7 @@ - - diff --git a/src/AtomUI.Controls/DatePicker/Themes/RangeDatePickerFlyoutPresenterTheme.axaml b/src/AtomUI.Controls/DatePicker/Themes/RangeDatePickerFlyoutPresenterTheme.axaml deleted file mode 100644 index dd1edcbf6..000000000 --- a/src/AtomUI.Controls/DatePicker/Themes/RangeDatePickerFlyoutPresenterTheme.axaml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file