feat: implement month syncing.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public sealed class CalendarContext(int? year = null, int? month = null, int? startYear = null, int? endYear = null)
|
||||
public sealed class CalendarContext(int? year = null, int? month = null, int? startYear = null, int? endYear = null): IComparable<CalendarContext>
|
||||
{
|
||||
public int? Year { get; } = year;
|
||||
public int? Month { get; } = month;
|
||||
@@ -64,4 +64,13 @@ public sealed class CalendarContext(int? year = null, int? month = null, int? st
|
||||
{
|
||||
return new CalendarContext(Year - 1, Month, StartYear, EndYear);
|
||||
}
|
||||
|
||||
public int CompareTo(CalendarContext? other)
|
||||
{
|
||||
if (ReferenceEquals(this, other)) return 0;
|
||||
if (ReferenceEquals(null, other)) return 1;
|
||||
var yearComparison = Nullable.Compare(Year, other.Year);
|
||||
if (yearComparison != 0) return yearComparison;
|
||||
return Nullable.Compare(Month, other.Month);
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,10 @@ public class CalendarView : TemplatedControl
|
||||
|
||||
private void OnContextDateChanged(AvaloniaPropertyChangedEventArgs<CalendarContext> args)
|
||||
{
|
||||
ContextDateChanged?.Invoke(this, args.NewValue.Value);
|
||||
if (!_dateContextSyncing)
|
||||
{
|
||||
ContextDateChanged?.Invoke(this, args.NewValue.Value);
|
||||
}
|
||||
//UpdateDayButtons();
|
||||
//UpdateYearButtons();
|
||||
}
|
||||
@@ -571,4 +574,19 @@ public class CalendarView : TemplatedControl
|
||||
base.OnPointerExited(e);
|
||||
DatePreviewed?.Invoke(this, new CalendarDayButtonEventArgs(null));
|
||||
}
|
||||
|
||||
private bool _dateContextSyncing = false;
|
||||
/// <summary>
|
||||
/// Used for syncing the context date for DateRangePicker. mark a flag to avoid infinitely loop.
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
internal void SyncContextDate(CalendarContext? context)
|
||||
{
|
||||
if (context is null) return;
|
||||
_dateContextSyncing = true;
|
||||
ContextDate = context;
|
||||
_dateContextSyncing = false;
|
||||
UpdateDayButtons();
|
||||
UpdateYearButtons();
|
||||
}
|
||||
}
|
||||
@@ -139,7 +139,7 @@ public class DatePicker: DatePickerBase, IClearControl
|
||||
if (_calendar is not null)
|
||||
{
|
||||
var d = SelectedDate ?? DateTime.Today;
|
||||
_calendar.ContextDate = new CalendarContext(date.Year, date.Month);
|
||||
_calendar.ContextDate = _calendar.ContextDate.With(year: date.Year, month: date.Month);
|
||||
_calendar.UpdateDayButtons();
|
||||
}
|
||||
_calendar?.MarkDates(startDate: date, endDate: date);
|
||||
@@ -152,7 +152,7 @@ public class DatePicker: DatePickerBase, IClearControl
|
||||
if (_calendar is not null)
|
||||
{
|
||||
var date = SelectedDate ?? DateTime.Today;
|
||||
_calendar.ContextDate = new CalendarContext(date.Year, date.Month);
|
||||
_calendar.ContextDate = _calendar.ContextDate.With(year: date.Year, month: date.Month);
|
||||
_calendar.UpdateDayButtons();
|
||||
}
|
||||
SetCurrentValue(IsDropdownOpenProperty, true);
|
||||
|
||||
@@ -32,6 +32,15 @@ public class DateRangePicker : DatePickerBase
|
||||
AvaloniaProperty.Register<DateRangePicker, DateTime?>(
|
||||
nameof(SelectedEndDate));
|
||||
|
||||
public static readonly StyledProperty<bool> EnableMonthSyncProperty = AvaloniaProperty.Register<DateRangePicker, bool>(
|
||||
nameof(EnableMonthSync));
|
||||
|
||||
public bool EnableMonthSync
|
||||
{
|
||||
get => GetValue(EnableMonthSyncProperty);
|
||||
set => SetValue(EnableMonthSyncProperty, value);
|
||||
}
|
||||
|
||||
private Button? _button;
|
||||
private CalendarView? _endCalendar;
|
||||
private TextBox? _endTextBox;
|
||||
@@ -103,11 +112,13 @@ public class DateRangePicker : DatePickerBase
|
||||
{
|
||||
_startCalendar.DateSelected -= OnDateSelected;
|
||||
_startCalendar.DatePreviewed -= OnDatePreviewed;
|
||||
_startCalendar.ContextDateChanged -= OnContextDateChanged;
|
||||
}
|
||||
if (_endCalendar != null)
|
||||
{
|
||||
_endCalendar.DateSelected -= OnDateSelected;
|
||||
_endCalendar.DatePreviewed -= OnDatePreviewed;
|
||||
_endCalendar.ContextDateChanged -= OnContextDateChanged;
|
||||
}
|
||||
_button = e.NameScope.Find<Button>(PART_Button);
|
||||
_popup = e.NameScope.Find<Popup>(PART_Popup);
|
||||
@@ -125,11 +136,33 @@ public class DateRangePicker : DatePickerBase
|
||||
{
|
||||
_startCalendar.DateSelected += OnDateSelected;
|
||||
_startCalendar.DatePreviewed += OnDatePreviewed;
|
||||
_startCalendar.ContextDateChanged += OnContextDateChanged;
|
||||
}
|
||||
if (_endCalendar != null)
|
||||
{
|
||||
_endCalendar.DateSelected += OnDateSelected;
|
||||
_endCalendar.DatePreviewed += OnDatePreviewed;
|
||||
_endCalendar.ContextDateChanged += OnContextDateChanged;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnContextDateChanged(object sender, CalendarContext e)
|
||||
{
|
||||
if(sender == _startCalendar)
|
||||
{
|
||||
bool needsUpdate = EnableMonthSync || _startCalendar?.ContextDate.CompareTo(_endCalendar?.ContextDate) >= 0;
|
||||
if (needsUpdate)
|
||||
{
|
||||
_endCalendar?.SyncContextDate(_startCalendar?.ContextDate.NextMonth());
|
||||
}
|
||||
}
|
||||
else if(sender == _endCalendar)
|
||||
{
|
||||
bool needsUpdate = EnableMonthSync || _endCalendar?.ContextDate.CompareTo(_startCalendar?.ContextDate) <= 0;
|
||||
if (needsUpdate)
|
||||
{
|
||||
_startCalendar?.SyncContextDate(_endCalendar?.ContextDate.PreviousMonth());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,7 +329,8 @@ public class DateRangePicker : DatePickerBase
|
||||
}
|
||||
if (_endCalendar is not null)
|
||||
{
|
||||
var date2 = SelectedEndDate ?? DateTime.Today;
|
||||
var date2 = SelectedEndDate ?? SelectedStartDate ?? DateTime.Today;
|
||||
if (SelectedEndDate is null) date2 = date2.AddMonths(1);
|
||||
_endCalendar.ContextDate = new CalendarContext(date2.Year, date2.Month);
|
||||
_endCalendar.UpdateDayButtons();
|
||||
_endCalendar?.MarkDates(SelectedStartDate, SelectedEndDate, _previewStart, _previewEnd);
|
||||
@@ -311,7 +345,7 @@ public class DateRangePicker : DatePickerBase
|
||||
{
|
||||
var date = SelectedStartDate ?? DateTime.Today;
|
||||
_startCalendar.ContextDate = new CalendarContext(date.Year, date.Month);
|
||||
// _startCalendar.UpdateDayButtons();
|
||||
_startCalendar.UpdateDayButtons();
|
||||
}
|
||||
|
||||
if (_endCalendar is not null)
|
||||
@@ -319,7 +353,7 @@ public class DateRangePicker : DatePickerBase
|
||||
var date2 = SelectedStartDate ?? DateTime.Today;
|
||||
date2 = date2.AddMonths(1);
|
||||
_endCalendar.ContextDate = new CalendarContext(date2.Year, date2.Month);
|
||||
// _endCalendar.UpdateDayButtons();
|
||||
_endCalendar.UpdateDayButtons();
|
||||
}
|
||||
SetCurrentValue(IsDropdownOpenProperty, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user