feat: WIP.
This commit is contained in:
@@ -8,6 +8,6 @@
|
||||
<StackPanel Margin="20" HorizontalAlignment="Left">
|
||||
<u:CalendarMonthView />
|
||||
<u:CalendarYearView />
|
||||
<u:Calendar/>
|
||||
<u:CalendarDisplayControl/>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<Design.PreviewWith>
|
||||
<StackPanel Margin="20" Spacing="5">
|
||||
<u:CalendarMonthView />
|
||||
<u:Calendar />
|
||||
<u:CalendarDisplayControl />
|
||||
</StackPanel>
|
||||
</Design.PreviewWith>
|
||||
<!-- Add Resources Here -->
|
||||
@@ -120,15 +120,15 @@
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
|
||||
<ControlTheme x:Key="{x:Type u:Calendar}" TargetType="u:Calendar">
|
||||
<ControlTheme x:Key="{x:Type u:CalendarDisplayControl}" TargetType="u:CalendarDisplayControl">
|
||||
<Setter Property="MinHeight" Value="300" />
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="u:Calendar">
|
||||
<ControlTemplate TargetType="u:CalendarDisplayControl">
|
||||
<Panel>
|
||||
<Grid RowDefinitions="Auto, *">
|
||||
<Grid Grid.Row="0" ColumnDefinitions="Auto, Auto,*, Auto, Auto">
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_PreviousYearButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_PreviousYearButton}"
|
||||
Grid.Column="0"
|
||||
HorizontalContentAlignment="Left"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
@@ -141,7 +141,7 @@
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_PreviousButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_PreviousButton}"
|
||||
Grid.Column="1"
|
||||
HorizontalContentAlignment="Left"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
<Grid Grid.Column="2" ColumnDefinitions="*, *">
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_YearButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_YearButton}"
|
||||
Grid.Column="0"
|
||||
HorizontalContentAlignment="Center"
|
||||
Content="2024"
|
||||
@@ -163,7 +163,7 @@
|
||||
IsVisible="{TemplateBinding IsMonthMode}"
|
||||
Theme="{DynamicResource BorderlessButton}" />
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_MonthButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_MonthButton}"
|
||||
Grid.Column="1"
|
||||
HorizontalContentAlignment="Center"
|
||||
Content="Apr"
|
||||
@@ -171,7 +171,7 @@
|
||||
IsVisible="{TemplateBinding IsMonthMode}"
|
||||
Theme="{DynamicResource BorderlessButton}" />
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_HeaderButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_HeaderButton}"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
IsVisible="{TemplateBinding IsMonthMode, Converter={x:Static BoolConverters.Not}}"
|
||||
@@ -181,7 +181,7 @@
|
||||
</Grid>
|
||||
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_NextButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_NextButton}"
|
||||
Grid.Column="3"
|
||||
HorizontalContentAlignment="Left"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
@@ -193,7 +193,7 @@
|
||||
Foreground="{DynamicResource CalendarItemIconForeground}" />
|
||||
</Button>
|
||||
<Button
|
||||
Name="{x:Static u:Calendar.PART_NextYearButton}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_NextYearButton}"
|
||||
Grid.Column="4"
|
||||
HorizontalContentAlignment="Left"
|
||||
Foreground="{TemplateBinding Foreground}"
|
||||
@@ -206,12 +206,12 @@
|
||||
</Button>
|
||||
</Grid>
|
||||
<u:CalendarMonthView
|
||||
Name="{x:Static u:Calendar.PART_MonthView}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_MonthView}"
|
||||
Grid.Row="1"
|
||||
VerticalAlignment="Top"
|
||||
IsVisible="{TemplateBinding IsMonthMode}" />
|
||||
<u:CalendarYearView
|
||||
Name="{x:Static u:Calendar.PART_YearView}"
|
||||
Name="{x:Static u:CalendarDisplayControl.PART_YearView}"
|
||||
Grid.Row="1"
|
||||
Width="{Binding #PART_MonthView.Bounds.Width}"
|
||||
Height="{Binding #PART_MonthView.Bounds.Height}"
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Metadata;
|
||||
using Avalonia.Controls.Mixins;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Irihi.Avalonia.Shared.Common;
|
||||
using Irihi.Avalonia.Shared.Helpers;
|
||||
using Ursa.EventArgs;
|
||||
|
||||
namespace Ursa.Controls;
|
||||
|
||||
[PseudoClasses(PseudoClassName.PC_Pressed, PseudoClassName.PC_Selected,
|
||||
PC_StartDate, PC_EndDate, PC_PreviewStartDate, PC_PreviewEndDate, PC_InRange, PC_Today, PC_Blackout, PC_NotCurrentMonth)]
|
||||
public class CalendarDayButton: ContentControl
|
||||
[PseudoClasses(PseudoClassName.PC_Pressed, PseudoClassName.PC_Selected,
|
||||
PC_StartDate, PC_EndDate, PC_PreviewStartDate, PC_PreviewEndDate, PC_InRange, PC_Today, PC_Blackout,
|
||||
PC_NotCurrentMonth)]
|
||||
public class CalendarDayButton : ContentControl
|
||||
{
|
||||
public const string PC_StartDate = ":start-date";
|
||||
public const string PC_EndDate = ":end-date";
|
||||
@@ -23,10 +21,46 @@ public class CalendarDayButton: ContentControl
|
||||
public const string PC_Today = ":today";
|
||||
public const string PC_NotCurrentMonth = ":not-current-month";
|
||||
public const string PC_Blackout = ":blackout";
|
||||
|
||||
internal Calendar? Owner { get; set; }
|
||||
|
||||
private static HashSet<string> _pseudoClasses =
|
||||
[
|
||||
PseudoClassName.PC_Selected, PC_EndDate, PC_PreviewStartDate,
|
||||
PC_PreviewEndDate, PseudoClassName.PC_Selected, PC_InRange
|
||||
];
|
||||
|
||||
public static readonly RoutedEvent<CalendarDayButtonEventArgs> DateSelectedEvent =
|
||||
RoutedEvent.Register<CalendarDayButton, CalendarDayButtonEventArgs>(
|
||||
nameof(DateSelected), RoutingStrategies.Bubble);
|
||||
|
||||
public static readonly RoutedEvent<CalendarDayButtonEventArgs> DatePreviewedEvent =
|
||||
RoutedEvent.Register<CalendarDayButton, CalendarDayButtonEventArgs>(
|
||||
nameof(DatePreviewed), RoutingStrategies.Bubble);
|
||||
|
||||
private bool _isBlackout;
|
||||
|
||||
private bool _isEndDate;
|
||||
|
||||
private bool _isInRange;
|
||||
|
||||
private bool _isNotCurrentMonth;
|
||||
|
||||
private bool _isPreviewEndDate;
|
||||
|
||||
private bool _isPreviewStartDate;
|
||||
|
||||
private bool _isSelected;
|
||||
|
||||
private bool _isStartDate;
|
||||
|
||||
private bool _isToday;
|
||||
|
||||
static CalendarDayButton()
|
||||
{
|
||||
PressedMixin.Attach<CalendarDayButton>();
|
||||
}
|
||||
|
||||
// internal CalendarDisplayControl? Owner { get; set; }
|
||||
|
||||
public bool IsToday
|
||||
{
|
||||
get => _isToday;
|
||||
@@ -36,30 +70,27 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PC_Today, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isStartDate;
|
||||
|
||||
public bool IsStartDate
|
||||
{
|
||||
get => _isStartDate;
|
||||
set
|
||||
{
|
||||
_isStartDate = value;
|
||||
PseudoClasses.Set(PC_StartDate, value);
|
||||
SetPseudoClass(PC_StartDate);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isEndDate;
|
||||
|
||||
public bool IsEndDate
|
||||
{
|
||||
get => _isEndDate;
|
||||
set
|
||||
{
|
||||
_isEndDate = value;
|
||||
PseudoClasses.Set(PC_EndDate, value);
|
||||
SetPseudoClass(PC_EndDate);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isPreviewStartDate;
|
||||
|
||||
public bool IsPreviewStartDate
|
||||
{
|
||||
get => _isPreviewStartDate;
|
||||
@@ -69,8 +100,7 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PC_PreviewStartDate, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isPreviewEndDate;
|
||||
|
||||
public bool IsPreviewEndDate
|
||||
{
|
||||
get => _isPreviewEndDate;
|
||||
@@ -80,8 +110,7 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PC_PreviewEndDate, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isInRange;
|
||||
|
||||
public bool IsInRange
|
||||
{
|
||||
get => _isInRange;
|
||||
@@ -92,7 +121,6 @@ public class CalendarDayButton: ContentControl
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isSelected;
|
||||
public bool IsSelected
|
||||
{
|
||||
get => _isSelected;
|
||||
@@ -102,10 +130,9 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PseudoClassName.PC_Selected, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isBlackout;
|
||||
|
||||
/// <summary>
|
||||
/// Notice: IsBlackout is not equivalent to not IsEnabled. Blackout dates still react to pointerover actions.
|
||||
/// Notice: IsBlackout is not equivalent to not IsEnabled. Blackout dates still react to pointerover actions.
|
||||
/// </summary>
|
||||
public bool IsBlackout
|
||||
{
|
||||
@@ -116,10 +143,10 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PC_Blackout, value);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _isNotCurrentMonth;
|
||||
|
||||
/// <summary>
|
||||
/// Notice: IsNotCurrentMonth is not equivalent to not IsEnabled. Not current month dates still react to pointerover and press action.
|
||||
/// Notice: IsNotCurrentMonth is not equivalent to not IsEnabled. Not current month dates still react to pointerover
|
||||
/// and press action.
|
||||
/// </summary>
|
||||
public bool IsNotCurrentMonth
|
||||
{
|
||||
@@ -130,33 +157,23 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PC_NotCurrentMonth, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly RoutedEvent<CalendarDayButtonEventArgs> DateSelectedEvent = RoutedEvent.Register<CalendarDayButton, CalendarDayButtonEventArgs>(
|
||||
nameof(DateSelected), RoutingStrategies.Bubble);
|
||||
|
||||
|
||||
public event EventHandler<CalendarDayButtonEventArgs> DateSelected
|
||||
{
|
||||
add => AddHandler(DateSelectedEvent, value);
|
||||
remove => RemoveHandler(DateSelectedEvent, value);
|
||||
}
|
||||
|
||||
public static readonly RoutedEvent<CalendarDayButtonEventArgs> DatePreviewedEvent = RoutedEvent.Register<CalendarDayButton, CalendarDayButtonEventArgs>(
|
||||
nameof(DatePreviewed), RoutingStrategies.Bubble);
|
||||
|
||||
|
||||
public event EventHandler<CalendarDayButtonEventArgs> DatePreviewed
|
||||
{
|
||||
add => AddHandler(DateSelectedEvent, value);
|
||||
remove => RemoveHandler(DateSelectedEvent, value);
|
||||
}
|
||||
|
||||
static CalendarDayButton()
|
||||
{
|
||||
PressedMixin.Attach<CalendarDayButton>();
|
||||
remove => RemoveHandler(DateSelectedEvent, value);
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
{
|
||||
base.OnApplyTemplate(e);
|
||||
/*
|
||||
PseudoClasses.Set(PC_Today, IsToday);
|
||||
PseudoClasses.Set(PC_StartDate, IsStartDate);
|
||||
PseudoClasses.Set(PC_EndDate, IsEndDate);
|
||||
@@ -164,23 +181,40 @@ public class CalendarDayButton: ContentControl
|
||||
PseudoClasses.Set(PC_PreviewEndDate, IsPreviewEndDate);
|
||||
PseudoClasses.Set(PC_InRange, IsInRange);
|
||||
PseudoClasses.Set(PseudoClassName.PC_Selected, IsSelected);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
{
|
||||
base.OnPointerPressed(e);
|
||||
if (this.DataContext is DateTime d)
|
||||
{
|
||||
if (DataContext is DateTime d)
|
||||
RaiseEvent(new CalendarDayButtonEventArgs(d) { RoutedEvent = DateSelectedEvent, Source = this });
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnPointerEntered(PointerEventArgs e)
|
||||
{
|
||||
base.OnPointerEntered(e);
|
||||
if (this.DataContext is DateTime d)
|
||||
{
|
||||
if (DataContext is DateTime d)
|
||||
RaiseEvent(new CalendarDayButtonEventArgs(d) { RoutedEvent = DateSelectedEvent, Source = this });
|
||||
}
|
||||
|
||||
internal void ResetSelection()
|
||||
{
|
||||
foreach (var pc in _pseudoClasses)
|
||||
{
|
||||
PseudoClasses.Set(pc, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetPseudoClass(string s)
|
||||
{
|
||||
if (_pseudoClasses.Contains(s))
|
||||
{
|
||||
foreach (var pc in _pseudoClasses)
|
||||
{
|
||||
PseudoClasses.Set(pc, false);
|
||||
}
|
||||
}
|
||||
PseudoClasses.Set(s, true);
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace Ursa.Controls;
|
||||
[TemplatePart(PART_HeaderButton, typeof(Button))]
|
||||
[TemplatePart(PART_MonthView, typeof(CalendarMonthView))]
|
||||
[TemplatePart(PART_YearView, typeof(CalendarYearView))]
|
||||
public class Calendar: TemplatedControl
|
||||
public class CalendarDisplayControl: TemplatedControl
|
||||
{
|
||||
public const string PART_NextYearButton = "PART_NextYearButton";
|
||||
public const string PART_PreviousYearButton = "PART_PreviousYearButton";
|
||||
@@ -37,7 +37,7 @@ public class Calendar: TemplatedControl
|
||||
private Button? _headerButton;
|
||||
|
||||
|
||||
public static readonly StyledProperty<DateTime> SelectedDateProperty = AvaloniaProperty.Register<Calendar, DateTime>(nameof(SelectedDate), DateTime.Now);
|
||||
public static readonly StyledProperty<DateTime> SelectedDateProperty = AvaloniaProperty.Register<CalendarDisplayControl, DateTime>(nameof(SelectedDate), DateTime.Now);
|
||||
public DateTime SelectedDate
|
||||
{
|
||||
get => GetValue(SelectedDateProperty);
|
||||
@@ -45,7 +45,7 @@ public class Calendar: TemplatedControl
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<DayOfWeek> FirstDayOfWeekProperty =
|
||||
AvaloniaProperty.Register<Calendar, DayOfWeek>(nameof(FirstDayOfWeek),
|
||||
AvaloniaProperty.Register<CalendarDisplayControl, DayOfWeek>(nameof(FirstDayOfWeek),
|
||||
defaultValue: DateTimeHelper.GetCurrentDateTimeFormatInfo().FirstDayOfWeek);
|
||||
public DayOfWeek FirstDayOfWeek
|
||||
{
|
||||
@@ -53,7 +53,7 @@ public class Calendar: TemplatedControl
|
||||
set => SetValue(FirstDayOfWeekProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<bool> IsTodayHighlightedProperty = AvaloniaProperty.Register<Calendar, bool>(nameof(IsTodayHighlighted), true);
|
||||
public static readonly StyledProperty<bool> IsTodayHighlightedProperty = AvaloniaProperty.Register<CalendarDisplayControl, bool>(nameof(IsTodayHighlighted), true);
|
||||
public bool IsTodayHighlighted
|
||||
{
|
||||
get => GetValue(IsTodayHighlightedProperty);
|
||||
@@ -61,7 +61,7 @@ public class Calendar: TemplatedControl
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<AvaloniaList<DateRange>?> BlackoutDatesProperty =
|
||||
AvaloniaProperty.Register<Calendar, AvaloniaList<DateRange>?>(
|
||||
AvaloniaProperty.Register<CalendarDisplayControl, AvaloniaList<DateRange>?>(
|
||||
nameof(BlackoutDates));
|
||||
|
||||
public AvaloniaList<DateRange>? BlackoutDates
|
||||
@@ -70,7 +70,7 @@ public class Calendar: TemplatedControl
|
||||
set => SetValue(BlackoutDatesProperty, value);
|
||||
}
|
||||
|
||||
public static readonly StyledProperty<IDateSelector?> BlackoutDateRuleProperty = AvaloniaProperty.Register<Calendar, IDateSelector?>(
|
||||
public static readonly StyledProperty<IDateSelector?> BlackoutDateRuleProperty = AvaloniaProperty.Register<CalendarDisplayControl, IDateSelector?>(
|
||||
nameof(BlackoutDateRule));
|
||||
|
||||
public IDateSelector? BlackoutDateRule
|
||||
@@ -81,7 +81,7 @@ public class Calendar: TemplatedControl
|
||||
|
||||
private bool _isMonthMode = true;
|
||||
|
||||
public static readonly DirectProperty<Calendar, bool> IsMonthModeProperty = AvaloniaProperty.RegisterDirect<Calendar, bool>(
|
||||
public static readonly DirectProperty<CalendarDisplayControl, bool> IsMonthModeProperty = AvaloniaProperty.RegisterDirect<CalendarDisplayControl, bool>(
|
||||
nameof(IsMonthMode), o => o.IsMonthMode, (o, v) => o.IsMonthMode = v);
|
||||
|
||||
public bool IsMonthMode
|
||||
@@ -153,14 +153,14 @@ public class Calendar: TemplatedControl
|
||||
{
|
||||
SetCurrentValue(IsMonthModeProperty, false);
|
||||
if (_yearView is null) return;
|
||||
_headerButton?.SetValue(Button.ContentProperty, _yearView.ContextDate.Year);
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty, _yearView.ContextDate.Year);
|
||||
_yearView?.UpdateMode(CalendarYearViewMode.Month);
|
||||
}
|
||||
|
||||
private void OnYearButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_yearView is null) return;
|
||||
_headerButton?.SetValue(Button.ContentProperty,
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty,
|
||||
_yearView?.ContextDate.Year + "-" + (_yearView?.ContextDate.Year + 10));
|
||||
_yearView?.UpdateMode(CalendarYearViewMode.Year);
|
||||
SetCurrentValue(IsMonthModeProperty, false);
|
||||
@@ -9,7 +9,8 @@ using Avalonia.Layout;
|
||||
namespace Ursa.Controls;
|
||||
|
||||
/// <summary>
|
||||
/// Show days in a month.
|
||||
/// Show days in a month. CalendarMonthView itself doesn't handle any date range selection logic.
|
||||
/// it provides a method to mark preview range and selection range. The range limit may out of current displayed month.
|
||||
/// </summary>
|
||||
[TemplatePart(PART_Grid, typeof(Grid))]
|
||||
public class CalendarMonthView : TemplatedControl
|
||||
@@ -32,7 +33,7 @@ public class CalendarMonthView : TemplatedControl
|
||||
view.OnDayOfWeekChanged(args));
|
||||
}
|
||||
|
||||
internal Calendar? Owner { get; set; }
|
||||
internal CalendarDisplayControl? Owner { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The DateTime used to generate the month view. This date will be within the month.
|
||||
@@ -156,6 +157,30 @@ public class CalendarMonthView : TemplatedControl
|
||||
public event EventHandler<CalendarDayButtonEventArgs>? OnDateSelected;
|
||||
public event EventHandler<CalendarDayButtonEventArgs>? OnDatePreviewed;
|
||||
|
||||
public void MarkDates(DateTime? startDate = null, DateTime? endDate = null, DateTime? previewStartDate = null, DateTime? previewEndDate = null)
|
||||
{
|
||||
if (_grid?.Children is null) return;
|
||||
DateTime start = startDate ?? DateTime.MaxValue;
|
||||
DateTime end = endDate ?? DateTime.MinValue;
|
||||
DateTime previewStart = previewStartDate ?? DateTime.MaxValue;
|
||||
DateTime previewEnd = previewEndDate ?? DateTime.MinValue;
|
||||
DateTime rangeStart = DateTimeHelper.Min(start, previewStart);
|
||||
DateTime rangeEnd = DateTimeHelper.Max(end, previewEnd);
|
||||
foreach (var child in _grid.Children)
|
||||
{
|
||||
if (child is not CalendarDayButton { DataContext: DateTime d } button) continue;
|
||||
if(d.Month != _contextDate.Month) continue;
|
||||
button.ResetSelection();
|
||||
if (d < rangeEnd && d > rangeStart) button.IsInRange = true;
|
||||
if (d == previewStart) button.IsPreviewStartDate = true;
|
||||
if (d == previewEnd) button.IsPreviewEndDate = true;
|
||||
if (d == startDate) button.IsStartDate = true;
|
||||
if (d == endDate) button.IsEndDate = true;
|
||||
if (d == startDate && d == endDate) button.IsSelected = true;
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete]
|
||||
public void MarkSelection(DateTime? start, DateTime? end)
|
||||
{
|
||||
if (_grid?.Children is null) return;
|
||||
|
||||
@@ -12,39 +12,43 @@ internal enum CalendarYearViewMode
|
||||
{
|
||||
Month,
|
||||
Year,
|
||||
|
||||
// The button represents 10 years.
|
||||
YearRange,
|
||||
}
|
||||
YearRange
|
||||
}
|
||||
|
||||
[PseudoClasses(PC_Range, PseudoClassName.PC_Selected)]
|
||||
public class CalendarYearButton: ContentControl
|
||||
public class CalendarYearButton : ContentControl
|
||||
{
|
||||
public const string PC_Range = ":range";
|
||||
|
||||
public static readonly RoutedEvent<CalendarYearButtonEventArgs> ItemSelectedEvent =
|
||||
RoutedEvent.Register<CalendarYearButton, CalendarYearButtonEventArgs>(
|
||||
nameof(ItemSelected), RoutingStrategies.Bubble);
|
||||
|
||||
static CalendarYearButton()
|
||||
{
|
||||
PressedMixin.Attach<CalendarYearButton>();
|
||||
}
|
||||
|
||||
|
||||
internal int Year { get; private set; }
|
||||
|
||||
|
||||
internal int Month { get; private set; }
|
||||
|
||||
|
||||
internal int StartYear { get; private set; }
|
||||
|
||||
|
||||
internal int EndYear { get; private set; }
|
||||
|
||||
|
||||
internal CalendarYearViewMode Mode { get; private set; }
|
||||
|
||||
public static readonly RoutedEvent<CalendarYearButtonEventArgs> ItemSelectedEvent = RoutedEvent.Register<CalendarYearButton, CalendarYearButtonEventArgs>(
|
||||
nameof(ItemSelected), RoutingStrategies.Bubble);
|
||||
|
||||
|
||||
public event EventHandler<CalendarDayButtonEventArgs> ItemSelected
|
||||
{
|
||||
add => AddHandler(ItemSelectedEvent, value);
|
||||
remove => RemoveHandler(ItemSelectedEvent, value);
|
||||
}
|
||||
|
||||
internal void SetValues(CalendarYearViewMode mode, DateTime contextDate, int? month = null, int? year = null, int? startYear = null, int? endYear = null)
|
||||
internal void SetValues(CalendarYearViewMode mode, DateTime contextDate, int? month = null, int? year = null,
|
||||
int? startYear = null, int? endYear = null)
|
||||
{
|
||||
Debug.Assert(!(month is null && year is null && startYear is null && endYear is null));
|
||||
Mode = mode;
|
||||
@@ -66,6 +70,5 @@ public class CalendarYearButton: ContentControl
|
||||
base.OnPointerPressed(e);
|
||||
RaiseEvent(new CalendarYearButtonEventArgs(Mode, Year, Month, StartYear, EndYear)
|
||||
{ RoutedEvent = ItemSelectedEvent, Source = this });
|
||||
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,14 @@ namespace Ursa.Controls;
|
||||
|
||||
public class CalendarYearButtonEventArgs: RoutedEventArgs
|
||||
{
|
||||
internal int? Year { get; }
|
||||
internal int? Month { get; }
|
||||
internal int? StartYear { get; }
|
||||
internal int? EndYear { get; }
|
||||
public int? Year { get; }
|
||||
public int? Month { get; }
|
||||
public int? StartYear { get; }
|
||||
public int? EndYear { get; }
|
||||
internal CalendarYearViewMode Mode { get; }
|
||||
internal CalendarYearButtonEventArgs( CalendarYearViewMode mode, int? year, int? month, int? startYear, int? endYear )
|
||||
|
||||
/// <inheritdoc />
|
||||
internal CalendarYearButtonEventArgs(CalendarYearViewMode mode, int? year, int? month, int? startYear, int? endYear )
|
||||
{
|
||||
Year = year;
|
||||
Month = month;
|
||||
|
||||
@@ -32,5 +32,14 @@ internal static class DateTimeHelper
|
||||
{
|
||||
return (dt1.Year - dt2.Year) * 12 + dt1.Month - dt2.Month;
|
||||
}
|
||||
|
||||
|
||||
public static DateTime Min(DateTime d1, DateTime d2)
|
||||
{
|
||||
return d1.Ticks > d2.Ticks ? d2 : d1;
|
||||
}
|
||||
|
||||
public static DateTime Max(DateTime d1, DateTime d2)
|
||||
{
|
||||
return d1.Ticks < d2.Ticks ? d2 : d1;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user