Add DualMonthRangeDatePickerPresenter Control

Add DualMonthRangeDatePickerPresenter Control
This commit is contained in:
polarboy
2024-09-18 08:39:09 +08:00
parent 72c61a85f9
commit ccf268e69c
20 changed files with 697 additions and 16 deletions
@@ -26,6 +26,12 @@
Description="Date selection panel with time selection.">
<calendarView:DualMonthRangeCalendar IsSelectRangeStart="True" SecondarySelectedDate="2024-10-1"/>
</desktop:ShowCaseItem>
<desktop:ShowCaseItem
Title="With Time Picker"
Description="Date selection panel with time selection.">
<atom:RangeDatePicker IsShowTime="true"/>
</desktop:ShowCaseItem>
<!-- -->
<!-- <desktop:ShowCaseItem -->
<!-- Title="Need Confirm" -->
@@ -13,10 +13,10 @@ namespace AtomUI.Controls.CalendarView;
public class DateSelectedEventArgs : EventArgs
{
public DateTime? Value { get; }
public DateTime? Date { get; }
public DateSelectedEventArgs(DateTime? value)
{
Value = value;
Date = value;
}
}
@@ -13,7 +13,6 @@ using Avalonia.Input;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Threading;
namespace AtomUI.Controls.CalendarView;
+5 -7
View File
@@ -26,7 +26,7 @@ public class DatePicker : InfoPickerInput
AvaloniaProperty.Register<DatePicker, string?>(nameof(Format));
public static readonly StyledProperty<bool> IsShowTimeProperty =
AvaloniaProperty.Register<DatePicker, bool>(nameof(IsShowTime));
AvaloniaProperty.Register<DatePicker, bool>(nameof(IsShowTime), false);
public static readonly StyledProperty<bool> IsNeedConfirmProperty =
AvaloniaProperty.Register<DatePicker, bool>(nameof(IsNeedConfirm));
@@ -124,7 +124,7 @@ public class DatePicker : InfoPickerInput
return format;
}
public string FormatDateTime(DateTime? dateTime)
protected string FormatDateTime(DateTime? dateTime)
{
if (dateTime is null)
{
@@ -208,9 +208,9 @@ public class DatePicker : InfoPickerInput
private void HandleHoverDateTimeChanged(object? sender, DateSelectedEventArgs args)
{
if (args.Value.HasValue)
if (args.Date.HasValue)
{
Text = FormatDateTime(args.Value);
Text = FormatDateTime(args.Date);
}
else
{
@@ -226,9 +226,7 @@ public class DatePicker : InfoPickerInput
private void ClearHoverSelectedInfo()
{
DateTime? targetValue = default;
targetValue = SelectedDateTime;
Text = FormatDateTime(targetValue);
Text = FormatDateTime(SelectedDateTime);
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
@@ -267,7 +267,7 @@ internal class DatePickerPresenter : PickerPresenterBase
{
// 需要组合日期和时间
// 暂时没实现
var hoverDateTime = CollectDateTime(args.Value, TempSelectedTime);
var hoverDateTime = CollectDateTime(args.Date, TempSelectedTime);
HoverDateTimeChanged?.Invoke(this, new DateSelectedEventArgs(hoverDateTime));
}
@@ -5,7 +5,6 @@ using AtomUI.Theme.Data;
using AtomUI.Theme.Styling;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Data;
using Avalonia.Layout;
using Avalonia.Styling;
using PickerCalendar = AtomUI.Controls.CalendarView.Calendar;
@@ -0,0 +1,6 @@
namespace AtomUI.Controls;
internal class DualMonthRangeDatePickerPresenter : RangeDatePickerPresenter
{
}
@@ -0,0 +1,15 @@
using AtomUI.Theme.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class DualMonthRangeDatePickerPresenterTheme : DatePickerPresenterTheme
{
public DualMonthRangeDatePickerPresenterTheme() : this(typeof(DualMonthRangeDatePickerPresenter))
{
}
public DualMonthRangeDatePickerPresenterTheme(Type targetType) : base(targetType)
{
}
}
@@ -0,0 +1,415 @@
using System.Globalization;
using AtomUI.Controls.CalendarView;
using AtomUI.Controls.Internal;
using AtomUI.Controls.TimePickerLang;
using AtomUI.Data;
using AtomUI.Theme.Data;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
namespace AtomUI.Controls;
public class RangeDatePicker : RangeInfoPickerInput
{
#region 公共属性定义
public static readonly StyledProperty<DateTime?> RangeStartSelectedDateProperty =
AvaloniaProperty.Register<RangeDatePicker, DateTime?>(nameof(RangeStartSelectedDate),
defaultBindingMode: BindingMode.TwoWay,
enableDataValidation: true);
public static readonly StyledProperty<DateTime?> RangeEndSelectedDateProperty =
AvaloniaProperty.Register<RangeDatePicker, DateTime?>(nameof(RangeEndSelectedDate),
defaultBindingMode: BindingMode.TwoWay,
enableDataValidation: true);
public static readonly StyledProperty<DateTime?> RangeStartDefaultDateProperty =
AvaloniaProperty.Register<RangeDatePicker, DateTime?>(nameof(RangeStartDefaultDate),
enableDataValidation: true);
public static readonly StyledProperty<DateTime?> RangeEndDefaultDateProperty =
AvaloniaProperty.Register<RangeDatePicker, DateTime?>(nameof(RangeEndDefaultDate),
enableDataValidation: true);
public static readonly StyledProperty<bool> IsNeedConfirmProperty =
AvaloniaProperty.Register<RangeDatePicker, bool>(nameof(IsNeedConfirm));
public static readonly StyledProperty<bool> IsShowNowProperty =
DatePicker.IsShowNowProperty.AddOwner<RangeDatePicker>();
public static readonly StyledProperty<bool> IsShowTimeProperty =
DatePicker.IsShowTimeProperty.AddOwner<RangeDatePicker>();
public static readonly StyledProperty<ClockIdentifierType> ClockIdentifierProperty =
DatePicker.ClockIdentifierProperty.AddOwner<RangeDatePicker>();
public static readonly StyledProperty<string?> FormatProperty =
DatePicker.FormatProperty.AddOwner<RangeDatePicker>();
public DateTime? RangeStartSelectedDate
{
get => GetValue(RangeStartSelectedDateProperty);
set => SetValue(RangeStartSelectedDateProperty, value);
}
public DateTime? RangeEndSelectedDate
{
get => GetValue(RangeEndSelectedDateProperty);
set => SetValue(RangeEndSelectedDateProperty, value);
}
public DateTime? RangeStartDefaultDate
{
get => GetValue(RangeStartDefaultDateProperty);
set => SetValue(RangeStartDefaultDateProperty, value);
}
public DateTime? RangeEndDefaultDate
{
get => GetValue(RangeEndDefaultDateProperty);
set => SetValue(RangeEndDefaultDateProperty, 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);
}
public string? Format
{
get => GetValue(FormatProperty);
set => SetValue(FormatProperty, value);
}
#endregion
private RangeDatePickerPresenter? _pickerPresenter;
protected override Flyout CreatePickerFlyout()
{
return new RangeDatePickerFlyout();
}
public override void Clear()
{
base.Clear();
RangeStartSelectedDate = null;
RangeEndSelectedDate = null;
}
public void Reset()
{
RangeStartSelectedDate = RangeStartDefaultDate;
RangeEndSelectedDate = RangeEndDefaultDate;
}
protected override void NotifyFlyoutPresenterCreated(Control flyoutPresenter)
{
if (flyoutPresenter is RangeDatePickerFlyoutPresenter rangeDatePickerFlyoutPresenter)
{
BindUtils.RelayBind(this, IsShowTimeProperty, rangeDatePickerFlyoutPresenter, RangeDatePickerFlyoutPresenter.IsShowTimeProperty);
rangeDatePickerFlyoutPresenter.AttachedToVisualTree += (sender, args) =>
{
_pickerPresenter = rangeDatePickerFlyoutPresenter.DatePickerPresenter;
ConfigurePickerPresenter(_pickerPresenter);
};
}
}
private void ConfigurePickerPresenter(RangeDatePickerPresenter? presenter)
{
if (presenter is null)
{
return;
}
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();
if (_pickerPresenter is not null)
{
_pickerPresenter.ChoosingStatueChanged += HandleChoosingStatueChanged;
_pickerPresenter.HoverDateTimeChanged += HandleHoverDateTimeChanged;
_pickerPresenter.Confirmed += HandleConfirmed;
}
}
protected override void NotifyFlyoutAboutToClose(bool selectedIsValid)
{
base.NotifyFlyoutAboutToClose(selectedIsValid);
if (_pickerPresenter is not null)
{
_pickerPresenter.ChoosingStatueChanged -= HandleChoosingStatueChanged;
_pickerPresenter.HoverDateTimeChanged -= HandleHoverDateTimeChanged;
_pickerPresenter.Confirmed -= HandleConfirmed;
}
}
private void HandleChoosingStatueChanged(object? sender, ChoosingStatusEventArgs args)
{
_isChoosing = args.IsChoosing;
UpdatePseudoClasses();
if (!args.IsChoosing)
{
ClearHoverSelectedInfo();
}
}
private void ClearHoverSelectedInfo()
{
if (RangeActivatedPart == RangeActivatedPart.Start)
{
Text = FormatDateTime(RangeStartSelectedDate);
}
else if (RangeActivatedPart == RangeActivatedPart.End)
{
SecondaryText = FormatDateTime(RangeEndSelectedDate);
}
}
private string GetEffectiveFormat()
{
if (Format is not null)
{
return Format;
}
var format = "yyyy-MM-dd";
if (IsShowTime)
{
if (ClockIdentifier == ClockIdentifierType.HourClock12)
{
format = $"{format} hh:mm:ss tt";
}
else
{
format = $"{format} HH:mm:ss";
}
}
return format;
}
protected string FormatDateTime(DateTime? dateTime)
{
if (dateTime is null)
{
return string.Empty;
}
var format = GetEffectiveFormat();
if (ClockIdentifier == ClockIdentifierType.HourClock12)
{
var formatInfo = new DateTimeFormatInfo();
formatInfo.AMDesignator = LanguageResourceBinder.GetLangResource(TimePickerLangResourceKey.AMText)!;
formatInfo.PMDesignator = LanguageResourceBinder.GetLangResource(TimePickerLangResourceKey.PMText)!;
return dateTime.Value.ToString(format, formatInfo);
}
return dateTime.Value.ToString(format);
}
private void HandleHoverDateTimeChanged(object? sender, DateSelectedEventArgs args)
{
if (args.Date.HasValue)
{
if (RangeActivatedPart == RangeActivatedPart.Start)
{
Text = FormatDateTime(args.Date);
}
else if (RangeActivatedPart == RangeActivatedPart.End)
{
SecondaryText = FormatDateTime(RangeEndDefaultDate);
}
}
else
{
Text = null;
}
}
private void HandleConfirmed(object? sender, EventArgs args)
{
if (RangeActivatedPart == RangeActivatedPart.Start)
{
RangeStartSelectedDate = _pickerPresenter?.SelectedDateTime;
if (RangeEndSelectedDate is null)
{
RangeActivatedPart = RangeActivatedPart.End;
return;
}
}
else if (RangeActivatedPart == RangeActivatedPart.End)
{
RangeEndSelectedDate = _pickerPresenter?.SelectedDateTime;
if (RangeStartSelectedDate is null)
{
RangeActivatedPart = RangeActivatedPart.Start;
return;
}
}
ClosePickerFlyout();
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == RangeActivatedPartProperty)
{
HandleRangeActivatedPartChanged();
}
if (VisualRoot is not null)
{
if (change.Property == RangeStartSelectedDateProperty)
{
if (RangeStartSelectedDate.HasValue)
{
Text = FormatDateTime(RangeStartSelectedDate.Value);
}
else
{
ResetRangeStartDateValue();
}
}
else if (change.Property == RangeEndSelectedDateProperty)
{
if (RangeEndSelectedDate.HasValue)
{
SecondaryText = FormatDateTime(RangeEndSelectedDate.Value);
}
else
{
ResetRangeEndDateValue();
}
}
}
}
protected void ResetRangeStartDateValue()
{
if (_infoInputBox is not null)
{
if (RangeStartDefaultDate is not null)
{
_infoInputBox.Text = FormatDateTime(RangeStartDefaultDate.Value);
}
else
{
_infoInputBox.Clear();
}
}
}
protected void ResetRangeEndDateValue()
{
if (_secondaryInfoInputBox is not null)
{
if (RangeEndDefaultDate is not null)
{
_secondaryInfoInputBox.Text = FormatDateTime(RangeEndDefaultDate.Value);;
}
else
{
_secondaryInfoInputBox.Clear();
}
}
}
protected override void HandleRangeActivatedPartChanged()
{
SetupPickerIndicatorPosition();
if (RangeActivatedPart == RangeActivatedPart.Start)
{
_infoInputBox!.Focus();
if (RangeEndSelectedDate is null)
{
ResetRangeStartDateValue();
}
if (_pickerPresenter is not null)
{
_pickerPresenter.SelectedDateTime = RangeStartSelectedDate;
}
}
else if (RangeActivatedPart == RangeActivatedPart.End)
{
_secondaryInfoInputBox!.Focus();
if (RangeStartSelectedDate is null)
{
ResetRangeEndDateValue();
}
if (_pickerPresenter is not null)
{
_pickerPresenter.SelectedDateTime = RangeEndSelectedDate;
}
}
else
{
if (RangeStartSelectedDate is null)
{
ResetRangeStartDateValue();
}
if (RangeEndSelectedDate is null)
{
ResetRangeEndDateValue();
}
if (_pickerPresenter is not null)
{
_pickerPresenter.SelectedDateTime = null;
}
}
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
if (RangeStartDefaultDate is not null && RangeStartSelectedDate is null)
{
RangeStartSelectedDate = RangeStartDefaultDate;
}
if (RangeEndDefaultDate is not null && RangeEndSelectedDate is null)
{
RangeEndSelectedDate = RangeEndDefaultDate;
}
}
protected override bool ShowClearButtonPredicate()
{
return RangeStartSelectedDate is not null || RangeEndSelectedDate is not null;
}
}
@@ -0,0 +1,17 @@
using AtomUI.Data;
using Avalonia;
using Avalonia.Controls;
namespace AtomUI.Controls;
internal class RangeDatePickerFlyout : Flyout
{
protected override Control CreatePresenter()
{
var presenter = new RangeDatePickerFlyoutPresenter();
BindUtils.RelayBind(this, IsShowArrowEffectiveProperty, presenter, IsShowArrowProperty);
CalculateShowArrowEffective();
SetupArrowPosition(Popup, presenter);
return presenter;
}
}
@@ -0,0 +1,54 @@
using Avalonia;
using Avalonia.Controls.Primitives;
namespace AtomUI.Controls;
internal class RangeDatePickerFlyoutPresenter : FlyoutPresenter
{
#region 公共属性定义
public static readonly StyledProperty<bool> IsShowTimeProperty =
DatePicker.IsShowTimeProperty.AddOwner<RangeDatePickerFlyoutPresenter>();
public bool IsShowTime
{
get => GetValue(IsShowTimeProperty);
set => SetValue(IsShowTimeProperty, value);
}
#endregion
internal RangeDatePickerPresenter? DatePickerPresenter;
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(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();
}
Content = DatePickerPresenter;
}
}
@@ -0,0 +1,30 @@
using AtomUI.Theme.Styling;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class RangeDatePickerFlyoutPresenterTheme : ArrowDecoratedBoxTheme
{
public const string PickerPresenterContentPart = "PART_PickerPresenterContent";
public RangeDatePickerFlyoutPresenterTheme()
: this(typeof(RangeDatePickerFlyoutPresenter))
{
}
protected RangeDatePickerFlyoutPresenterTheme(Type targetType) : base(targetType)
{
}
protected override Control BuildContent(INameScope scope)
{
var datePickerPresenter = new RangeDatePickerPresenter()
{
Name = PickerPresenterContentPart,
};
datePickerPresenter.RegisterInNameScope(scope);
return datePickerPresenter;
}
}
@@ -0,0 +1,19 @@
using Avalonia;
namespace AtomUI.Controls;
internal class RangeDatePickerPresenter : DatePickerPresenter
{
#region 公共属性定义
public static readonly StyledProperty<DateTime?> SecondarySelectedDateTimeProperty =
AvaloniaProperty.Register<RangeDatePickerPresenter, DateTime?>(nameof(SecondarySelectedDateTime));
public DateTime? SecondarySelectedDateTime
{
get => GetValue(SecondarySelectedDateTimeProperty);
set => SetValue(SecondarySelectedDateTimeProperty, value);
}
#endregion
}
@@ -0,0 +1,50 @@
using AtomUI.Controls.Internal;
using AtomUI.Theme.Styling;
using Avalonia.Controls;
using Avalonia.Styling;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class RangeDatePickerTheme : RangeInfoPickerInputTheme
{
public RangeDatePickerTheme() : base(typeof(RangeDatePicker))
{
}
protected override PathIcon BuildInfoIcon(InfoPickerInput infoPickerInput, INameScope scope)
{
return new PathIcon()
{
Kind = "ClockCircleOutlined"
};
}
protected override void BuildStyles()
{
base.BuildStyles();
{
var infoInputBoxStyle = new Style(selector => selector.Nesting().Template().Name(InfoInputBoxPart));
infoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputMinWidth);
Add(infoInputBoxStyle);
var secondaryInfoInputBoxStyle = new Style(selector => selector.Nesting().Template().Name(SecondaryInfoInputBoxPart));
secondaryInfoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputMinWidth);
Add(secondaryInfoInputBoxStyle);
}
var withTimeStyle =
new Style(selector => selector.Nesting().PropertyEquals(DatePicker.IsShowTimeProperty, true));
withTimeStyle.Add(DatePicker.MinWidthProperty, DatePickerTokenResourceKey.PickerInputWithTimeMinWidth);
{
var infoInputBoxStyle = new Style(selector => selector.Nesting().Template().Name(InfoInputBoxPart));
infoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputMinWidth);
withTimeStyle.Add(infoInputBoxStyle);
var secondaryInfoInputBoxStyle = new Style(selector => selector.Nesting().Template().Name(SecondaryInfoInputBoxPart));
secondaryInfoInputBoxStyle.Add(TextBox.MinWidthProperty, DatePickerTokenResourceKey.PickerInputMinWidth);
withTimeStyle.Add(secondaryInfoInputBoxStyle);
}
Add(withTimeStyle);
}
}
@@ -0,0 +1,6 @@
namespace AtomUI.Controls;
internal class TimedRangeDatePickerPresenter : RangeDatePickerPresenter
{
}
@@ -0,0 +1,46 @@
using AtomUI.Controls.CalendarView;
using AtomUI.Theme.Styling;
using Avalonia.Controls;
using Avalonia.Controls.Templates;
using Avalonia.Layout;
namespace AtomUI.Controls;
[ControlThemeProvider]
internal class TimedRangeDatePickerPresenterTheme : DatePickerPresenterTheme
{
public TimedRangeDatePickerPresenterTheme() : this(typeof(TimedRangeDatePickerPresenter))
{
}
public TimedRangeDatePickerPresenterTheme(Type targetType) : base(targetType)
{
}
protected virtual Control BuildCalendarView(DatePickerPresenter presenter, INameScope scope)
{
var calendarLayout = new StackPanel()
{
Orientation = Orientation.Horizontal
};
var calendarView = new RangeCalendar()
{
Name = CalendarViewPart,
};
CreateTemplateParentBinding(calendarView, RangeCalendar.SelectedDateProperty, DatePickerPresenter.SelectedDateTimeProperty);
calendarView.RegisterInNameScope(scope);
calendarLayout.Children.Add(calendarView);
var timeView = new TimeView()
{
Name = TimeViewPart,
VerticalAlignment = VerticalAlignment.Top,
};
CreateTemplateParentBinding(timeView, TimeView.ClockIdentifierProperty, DatePickerPresenter.ClockIdentifierProperty);
CreateTemplateParentBinding(timeView, TimeView.IsVisibleProperty, DatePickerPresenter.IsShowTimeProperty);
timeView.RegisterInNameScope(scope);
calendarLayout.Children.Add(timeView);
return calendarLayout;
}
}
@@ -159,7 +159,7 @@ public abstract class PopupFlyoutBase : FlyoutBase, IPopupHostProvider
#endregion
IPopupHost? IPopupHostProvider.PopupHost => Popup?.Host;
IPopupHost? IPopupHostProvider.PopupHost => Popup.Host;
protected Popup Popup => _popupLazy.Value;
private readonly Lazy<Popup> _popupLazy;
@@ -591,4 +591,12 @@ public abstract class PopupFlyoutBase : FlyoutBase, IPopupHostProvider
//Add new classes
presenter.Classes.AddRange(classes);
}
/// <summary>
/// 有时候需要清空 Popup 的 Child控件,强制重新创建
/// </summary>
internal void ClearUpPopupChild()
{
Popup.Child = null;
}
}
@@ -38,6 +38,10 @@
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.DatePickerFlyoutPresenterTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.DatePickerPresenterTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.DatePickerTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.DualMonthRangeDatePickerPresenterTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.RangeDatePickerFlyoutPresenterTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.RangeDatePickerTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.TimedRangeDatePickerPresenterTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.EmptyIndicatorTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.ExpanderTheme());
ThemeManager.Current.RegisterControlTheme(new AtomUI.Controls.MenuFlyoutPresenterTheme());
@@ -200,6 +200,7 @@ public abstract class InfoPickerInput : TemplatedControl
_flyoutStateHelper.FlyoutAboutToShow += HandleFlyoutAboutToShow;
_flyoutStateHelper.FlyoutAboutToClose += HandleFlyoutAboutToClose;
_flyoutStateHelper.FlyoutOpened += HandleFlyoutOpened;
_flyoutStateHelper.FlyoutClosed += HandleFlyoutClosed;
_flyoutStateHelper.OpenFlyoutPredicate = FlyoutOpenPredicate;
_flyoutStateHelper.ClickHideFlyoutPredicate = ClickHideFlyoutPredicate;
}
@@ -238,11 +239,19 @@ public abstract class InfoPickerInput : TemplatedControl
NotifyFlyoutOpened();
}
protected virtual void NotifyFlyoutOpened()
{
}
private void HandleFlyoutClosed(object? sender, EventArgs args)
{
NotifyFlyoutClosed();
}
protected virtual void NotifyFlyoutClosed()
{
}
protected virtual bool ClickHideFlyoutPredicate(IPopupHostProvider hostProvider, RawPointerEventArgs args)
{
if (hostProvider.PopupHost != args.Root)
@@ -284,7 +284,7 @@ public abstract class RangeInfoPickerInput : InfoPickerInput
SetupPickerIndicatorPosition();
}
private void SetupPickerIndicatorPosition()
protected void SetupPickerIndicatorPosition()
{
if (_rangePickerIndicator is null ||
_decoratedBox is null ||