Refactor DatePicker Bindings

This commit is contained in:
chinboy
2025-08-27 14:43:53 +08:00
parent e55112a951
commit 26aeab35ee
8 changed files with 97 additions and 76 deletions
+5 -12
View File
@@ -4,8 +4,6 @@ using System.Reactive.Disposables;
using AtomUI.Collections.Pooled;
using AtomUI.Controls.Themes;
using AtomUI.Data;
using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
@@ -66,11 +64,11 @@ internal class CalendarItem : TemplatedControl
o => o.IsMonthViewMode,
(o, v) => o.IsMonthViewMode = v);
public static readonly StyledProperty<GridLength> DayTitleHeightProperty =
internal static readonly StyledProperty<GridLength> DayTitleHeightProperty =
AvaloniaProperty.Register<CalendarItem, GridLength>(
nameof(DayTitleHeight));
public static readonly StyledProperty<bool> IsMotionEnabledProperty =
internal static readonly StyledProperty<bool> IsMotionEnabledProperty =
MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<CalendarItem>();
/// <summary>
@@ -282,18 +280,10 @@ internal class CalendarItem : TemplatedControl
{
var childCount = Calendar.RowsPerMonth + Calendar.RowsPerMonth * Calendar.ColumnsPerMonth;
using var children = new PooledList<Control>(childCount);
_dayBtnBindingDisposables?.Dispose();
_dayBtnBindingDisposables = new CompositeDisposable(Calendar.RowsPerMonth * Calendar.ColumnsPerMonth + Calendar.ColumnsPerMonth);
for (var i = 0; i < Calendar.ColumnsPerMonth; i++)
{
var cell = DayTitleTemplate?.Build();
if (cell is TextBlock textBlockCell)
{
_dayBtnBindingDisposables.Add(TokenResourceBinder.CreateTokenBinding(textBlockCell,
HeightProperty, CalendarTokenKey.DayTitleHeight));
}
if (cell is not null)
{
cell.DataContext = string.Empty;
@@ -302,6 +292,9 @@ internal class CalendarItem : TemplatedControl
children.Add(cell);
}
}
_dayBtnBindingDisposables?.Dispose();
_dayBtnBindingDisposables = new CompositeDisposable(Calendar.RowsPerMonth * Calendar.ColumnsPerMonth);
EventHandler<PointerPressedEventArgs> cellMouseLeftButtonDown = HandleCellMouseLeftButtonDown;
EventHandler<PointerReleasedEventArgs> cellMouseLeftButtonUp = HandleCellMouseLeftButtonUp;
@@ -27,8 +27,7 @@ namespace AtomUI.Controls.CalendarView;
[TemplatePart(CalendarItemThemeConstants.NextButtonPart, typeof(IconButton))]
[TemplatePart(CalendarItemThemeConstants.NextMonthButtonPart, typeof(IconButton))]
[TemplatePart(CalendarItemThemeConstants.YearViewPart, typeof(Grid))]
internal class CalendarItem : TemplatedControl,
IResourceBindingManager
internal class CalendarItem : TemplatedControl, IResourceBindingManager
{
internal const string CalendarDisabledPC = ":calendardisabled";
@@ -70,8 +69,8 @@ internal class CalendarItem : TemplatedControl,
o => o.IsMonthViewMode,
(o, v) => o.IsMonthViewMode = v);
internal static readonly StyledProperty<bool> IsMotionEnabledProperty
= MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<CalendarItem>();
internal static readonly StyledProperty<bool> IsMotionEnabledProperty =
MotionAwareControlProperty.IsMotionEnabledProperty.AddOwner<CalendarItem>();
private bool _isMonthViewMode = true;
@@ -237,6 +236,9 @@ internal class CalendarItem : TemplatedControl,
/// Gets the Grid that hosts the content when in year or decade mode.
/// </summary>
internal Grid? YearView { get; set; }
private protected CompositeDisposable? DayBtnBindingDisposables;
private protected CompositeDisposable? MonthBtnBindingDisposables;
private void PopulateGrids()
{
@@ -250,6 +252,9 @@ internal class CalendarItem : TemplatedControl,
EventHandler<PointerPressedEventArgs> monthCalendarButtonMouseDown = HandleMonthCalendarButtonMouseDown;
EventHandler<PointerReleasedEventArgs> monthCalendarButtonMouseUp = HandleMonthCalendarButtonMouseUp;
EventHandler<PointerEventArgs> monthMouseEntered = HandleMonthMouseEntered;
MonthBtnBindingDisposables?.Dispose();
MonthBtnBindingDisposables = new CompositeDisposable(Calendar.RowsPerYear * Calendar.ColumnsPerYear);
for (var i = 0; i < Calendar.RowsPerYear; i++)
{
@@ -260,8 +265,8 @@ internal class CalendarItem : TemplatedControl,
if (Owner != null)
{
month.Owner = Owner;
BindUtils.RelayBind(Owner, Calendar.IsMotionEnabledProperty, month,
CalendarButton.IsMotionEnabledProperty);
MonthBtnBindingDisposables.Add(BindUtils.RelayBind(Owner, Calendar.IsMotionEnabledProperty, month,
CalendarButton.IsMotionEnabledProperty));
}
month.SetValue(Grid.RowProperty, i);
@@ -281,6 +286,8 @@ internal class CalendarItem : TemplatedControl,
{
if (MonthView != null)
{
DayBtnBindingDisposables?.Dispose();
DayBtnBindingDisposables = new CompositeDisposable(Calendar.RowsPerMonth * Calendar.ColumnsPerMonth);
PopulateMonthViewGrid(MonthView);
}
}
@@ -316,8 +323,8 @@ internal class CalendarItem : TemplatedControl,
if (Owner != null)
{
cell.Owner = Owner;
BindUtils.RelayBind(Owner, Calendar.IsMotionEnabledProperty, cell,
CalendarDayButton.IsMotionEnabledProperty);
DayBtnBindingDisposables?.Add(BindUtils.RelayBind(Owner, Calendar.IsMotionEnabledProperty, cell,
CalendarDayButton.IsMotionEnabledProperty));
}
cell.SetValue(Grid.RowProperty, i);
@@ -1,4 +1,5 @@
using AtomUI.Controls.Themes;
using System.Reactive.Disposables;
using AtomUI.Controls.Themes;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
@@ -217,7 +218,12 @@ internal class DualMonthCalendarItem : RangeCalendarItem
protected override void PopulateMonthViewsGrid()
{
base.PopulateMonthViewsGrid();
DayBtnBindingDisposables?.Dispose();
DayBtnBindingDisposables = new CompositeDisposable(Calendar.RowsPerMonth * Calendar.ColumnsPerMonth * 2);
if (MonthView != null)
{
PopulateMonthViewGrid(MonthView);
}
if (SecondaryMonthView != null)
{
PopulateMonthViewGrid(SecondaryMonthView);
+11 -7
View File
@@ -1,4 +1,5 @@
using System.Globalization;
using System.Reactive.Disposables;
using AtomUI.Controls.CalendarView;
using AtomUI.Controls.Primitives;
using AtomUI.Controls.TimePickerLang;
@@ -100,6 +101,7 @@ public class DatePicker : InfoPickerInput,
}
private DatePickerPresenter? _pickerPresenter;
private CompositeDisposable? _flyoutBindingDisposables;
/// <summary>
/// 清除时间选择器的值,不考虑默认值
@@ -164,13 +166,15 @@ 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);
_flyoutBindingDisposables?.Dispose();
_flyoutBindingDisposables = new CompositeDisposable(7);
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, flyout, DatePickerFlyout.IsMotionEnabledProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, flyout, DatePickerPresenter.IsMotionEnabledProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, SelectedDateTimeProperty, flyout, DatePickerPresenter.SelectedDateTimeProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsNeedConfirmProperty, flyout, DatePickerPresenter.IsNeedConfirmProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsShowNowProperty, flyout, DatePickerPresenter.IsShowNowProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsShowTimeProperty, flyout, DatePickerPresenter.IsShowTimeProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, ClockIdentifierProperty, flyout, DatePickerPresenter.ClockIdentifierProperty));
return flyout;
}
@@ -1,4 +1,5 @@
using AtomUI.Data;
using System.Reactive.Disposables;
using AtomUI.Data;
using Avalonia;
using Avalonia.Controls;
@@ -52,23 +53,25 @@ internal class DatePickerFlyout : Flyout
}
internal DatePickerPresenter? DatePickerPresenter { get; set; }
private CompositeDisposable? _presenterBindingDisposables;
protected override Control CreatePresenter()
{
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);
_presenterBindingDisposables?.Dispose();
_presenterBindingDisposables = new CompositeDisposable(7);
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, DatePickerPresenter, DatePickerPresenter.IsMotionEnabledProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, SelectedDateTimeProperty, DatePickerPresenter, DatePickerPresenter.SelectedDateTimeProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsNeedConfirmProperty, DatePickerPresenter, DatePickerPresenter.IsNeedConfirmProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowNowProperty, DatePickerPresenter, DatePickerPresenter.IsShowNowProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowTimeProperty, DatePickerPresenter, DatePickerPresenter.IsShowTimeProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ClockIdentifierProperty, DatePickerPresenter, DatePickerPresenter.ClockIdentifierProperty));
var flyoutPresenter = new FlyoutPresenter
{
Content = DatePickerPresenter
};
BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, flyoutPresenter, IsShowArrowProperty);
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, flyoutPresenter, IsShowArrowProperty));
CalculateShowArrowEffective();
SetupArrowPosition(Popup, flyoutPresenter);
@@ -1,4 +1,5 @@
using System.Globalization;
using System.Reactive.Disposables;
using AtomUI.Controls.CalendarView;
using AtomUI.Controls.Primitives;
using AtomUI.Controls.TimePickerLang;
@@ -117,6 +118,7 @@ public class RangeDatePicker : RangeInfoPickerInput,
private RangeDatePickerPresenter? _pickerPresenter;
private bool? _isNeedConfirmedBackup;
private CompositeDisposable? _flyoutBindingDisposables;
public RangeDatePicker()
{
@@ -127,14 +129,15 @@ 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);
_flyoutBindingDisposables?.Dispose();
_flyoutBindingDisposables = new CompositeDisposable(7);
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, flyout, RangeDatePickerFlyout.IsMotionEnabledProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, RangeStartSelectedDateProperty, flyout, RangeDatePickerFlyout.SelectedDateTimeProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, RangeEndSelectedDateProperty, flyout, RangeDatePickerFlyout.SecondarySelectedDateTimeProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, ClockIdentifierProperty, flyout, RangeDatePickerFlyout.ClockIdentifierProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsNeedConfirmProperty, flyout, RangeDatePickerFlyout.IsNeedConfirmProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsShowNowProperty, flyout, RangeDatePickerFlyout.IsShowNowProperty));
_flyoutBindingDisposables.Add(BindUtils.RelayBind(this, IsShowTimeProperty, flyout, RangeDatePickerFlyout.IsShowTimeProperty));
return flyout;
}
@@ -1,4 +1,5 @@
using AtomUI.Data;
using System.Reactive.Disposables;
using AtomUI.Data;
using Avalonia;
using Avalonia.Controls;
@@ -16,45 +17,47 @@ internal class RangeDatePickerFlyout : DatePickerFlyout
}
internal FlyoutPresenter? _flyoutPresenter;
private CompositeDisposable? _flyoutPresenterBindingDisposables;
private CompositeDisposable? _presenterBindingDisposables;
protected override Control CreatePresenter()
{
_flyoutPresenter = new FlyoutPresenter();
ConfigureDatePickerPresenter();
BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, _flyoutPresenter, IsShowArrowProperty);
_flyoutPresenterBindingDisposables?.Dispose();
_flyoutPresenterBindingDisposables = new CompositeDisposable(1);
ConfigureDatePickerPresenter(_flyoutPresenter);
_flyoutPresenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, _flyoutPresenter, IsShowArrowProperty));
CalculateShowArrowEffective();
SetupArrowPosition(Popup, _flyoutPresenter);
return _flyoutPresenter;
}
private void ConfigureDatePickerPresenter()
private void ConfigureDatePickerPresenter(FlyoutPresenter flyoutPresenter)
{
if (_flyoutPresenter != null)
_presenterBindingDisposables?.Dispose();
_presenterBindingDisposables = new CompositeDisposable(7);
DatePickerPresenter? presenter;
if (IsShowTime)
{
DatePickerPresenter? presenter;
if (IsShowTime)
presenter = new TimedRangeDatePickerPresenter()
{
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;
IsShowTime = true
};
}
else
{
presenter = new DualMonthRangeDatePickerPresenter();
}
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsMotionEnabledProperty, presenter, RangeDatePickerPresenter.IsMotionEnabledProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, SelectedDateTimeProperty, presenter, RangeDatePickerPresenter.SelectedDateTimeProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsNeedConfirmProperty, presenter, RangeDatePickerPresenter.IsNeedConfirmProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowNowProperty, presenter, RangeDatePickerPresenter.IsShowNowProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, IsShowTimeProperty, presenter, RangeDatePickerPresenter.IsShowTimeProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, ClockIdentifierProperty, presenter, RangeDatePickerPresenter.ClockIdentifierProperty));
_presenterBindingDisposables.Add(BindUtils.RelayBind(this, SecondarySelectedDateTimeProperty, presenter, RangeDatePickerPresenter.SecondarySelectedDateTimeProperty));
flyoutPresenter.Content = presenter;
DatePickerPresenter = presenter;
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
@@ -62,7 +65,10 @@ internal class RangeDatePickerFlyout : DatePickerFlyout
base.OnPropertyChanged(e);
if (e.Property == IsShowTimeProperty)
{
ConfigureDatePickerPresenter();
if (_flyoutPresenter != null)
{
ConfigureDatePickerPresenter(_flyoutPresenter);
}
}
}
}
@@ -43,7 +43,6 @@
<atom:IconButton
Name="{x:Static atom:DatePickerCalendarItemThemeConstants.NextButtonPart}"
Icon="{atom:IconProvider DoubleRightOutlined}"
Grid.Column="4" />
</Grid>
</UniformGrid>