feat: finally.
This commit is contained in:
@@ -161,6 +161,7 @@
|
||||
</ControlTheme>
|
||||
<ControlTheme x:Key="{x:Type u:CalendarView}" TargetType="u:CalendarView">
|
||||
<Setter Property="MinHeight" Value="300" />
|
||||
<Setter Property="MinWidth" Value="300" />
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate TargetType="u:CalendarView">
|
||||
<Panel>
|
||||
@@ -256,22 +257,6 @@
|
||||
</Panel>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
<Style Selector="^:month">
|
||||
<Style Selector="^ /template/ Button#PART_YearButton, ^ /template/ Button#PART_MonthButton,^ /template/ Grid#PART_MonthGrid">
|
||||
<Setter Property="Control.IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ Button#PART_HeaderButton, ^ /template/ Grid#PART_YearGrid">
|
||||
<Setter Property="Control.IsVisible" Value="False" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="^:not(:month)">
|
||||
<Style Selector="^ /template/ Button#PART_YearButton, ^ /template/ Button#PART_MonthButton,^ /template/ Grid#PART_MonthGrid">
|
||||
<Setter Property="Control.IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ Button#PART_HeaderButton, ^ /template/ Grid#PART_YearGrid">
|
||||
<Setter Property="Control.IsVisible" Value="True" />
|
||||
</Style>
|
||||
</Style>
|
||||
</ControlTheme>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
16
src/Ursa/Controls/DateTimePicker/CalendarContext.cs
Normal file
16
src/Ursa/Controls/DateTimePicker/CalendarContext.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public class CalendarContext(int? year = null, int? month = null, int? day = null)
|
||||
{
|
||||
public int? Year = year;
|
||||
public int? Month = month;
|
||||
public int? Day = day;
|
||||
public int? StartYear;
|
||||
public int? EndYear;
|
||||
|
||||
|
||||
public CalendarContext Clone()
|
||||
{
|
||||
return new CalendarContext(Year, Month, Day) { StartYear = StartYear, EndYear = EndYear };
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,6 @@ public class CalendarView : TemplatedControl
|
||||
ModeProperty.Changed.AddClassHandler<CalendarView, CalendarViewMode>((view, args) =>
|
||||
{
|
||||
view.PseudoClasses.Set(PC_Month, args.NewValue.Value == CalendarViewMode.Month);
|
||||
Debug.WriteLine(args.NewValue.Value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -79,7 +78,7 @@ public class CalendarView : TemplatedControl
|
||||
set => SetAndRaise(ModeProperty, ref _mode, value);
|
||||
}
|
||||
|
||||
public DateContext ContextDate { get; set; } = new();
|
||||
public CalendarContext ContextCalendar { get; set; } = new();
|
||||
|
||||
public bool IsTodayHighlighted
|
||||
{
|
||||
@@ -99,7 +98,7 @@ public class CalendarView : TemplatedControl
|
||||
private void OnFirstDayOfWeekChanged(AvaloniaPropertyChangedEventArgs<DayOfWeek> args)
|
||||
{
|
||||
UpdateMonthViewHeader(args.NewValue.Value);
|
||||
RefreshDayButtons();
|
||||
UpdateDayButtons();
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||
@@ -120,11 +119,12 @@ public class CalendarView : TemplatedControl
|
||||
Button.ClickEvent.AddHandler(OnHeaderMonthButtonClick, _monthButton);
|
||||
Button.ClickEvent.AddHandler(OnHeaderButtonClick, _headerButton);
|
||||
|
||||
ContextDate = new DateContext(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);
|
||||
ContextCalendar = new CalendarContext(DateTime.Today.Year, DateTime.Today.Month, DateTime.Today.Day);
|
||||
PseudoClasses.Set(PC_Month, Mode == CalendarViewMode.Month);
|
||||
GenerateGridElements();
|
||||
RefreshDayButtons();
|
||||
RefreshYearButtons();
|
||||
InitializeGridButtons();
|
||||
UpdateDayButtons();
|
||||
UpdateYearButtons();
|
||||
UpdateHeaderButtons();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -139,23 +139,32 @@ public class CalendarView : TemplatedControl
|
||||
if (Mode == CalendarViewMode.Year)
|
||||
{
|
||||
Mode = CalendarViewMode.Decade;
|
||||
RefreshYearButtons();
|
||||
var range = DateTimeHelper.GetDecadeViewRangeByYear(ContextCalendar.Year!.Value);
|
||||
ContextCalendar.StartYear = range.start;
|
||||
ContextCalendar.EndYear = range.end;
|
||||
UpdateHeaderButtons();
|
||||
UpdateYearButtons();
|
||||
return;
|
||||
}
|
||||
if(Mode == CalendarViewMode.Decade)
|
||||
{
|
||||
Mode = CalendarViewMode.Century;
|
||||
RefreshYearButtons();
|
||||
var range = DateTimeHelper.GetCenturyViewRangeByYear(ContextCalendar.StartYear!.Value);
|
||||
ContextCalendar.StartYear = range.start;
|
||||
ContextCalendar.EndYear = range.end;
|
||||
UpdateHeaderButtons();
|
||||
UpdateYearButtons();
|
||||
return;
|
||||
}
|
||||
if (Mode == CalendarViewMode.Century) return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate Buttons and labels for MonthView.
|
||||
/// Generate Buttons for YearView.
|
||||
/// Generate Buttons and labels for MonthView.
|
||||
/// Generate Buttons for YearView.
|
||||
/// This method should be called only once.
|
||||
/// </summary>
|
||||
private void GenerateGridElements()
|
||||
private void InitializeGridButtons()
|
||||
{
|
||||
// Generate Day titles (Sun, Mon, Tue, Wed, Thu, Fri, Sat) based on FirstDayOfWeek and culture.
|
||||
var count = 7 + 7 * 7;
|
||||
@@ -197,14 +206,13 @@ public class CalendarView : TemplatedControl
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshDayButtons()
|
||||
private void UpdateDayButtons()
|
||||
{
|
||||
if (_monthGrid is null) return;
|
||||
var children = _monthGrid.Children;
|
||||
var info = DateTimeHelper.GetCurrentDateTimeFormatInfo();
|
||||
var date = new DateTime(ContextDate.Year.Value, ContextDate.Month.Value, ContextDate.Day.Value);
|
||||
var dayBefore =
|
||||
PreviousMonthDays(date);
|
||||
var date = new DateTime(ContextCalendar.Year.Value, ContextCalendar.Month.Value, ContextCalendar.Day.Value);
|
||||
var dayBefore = PreviousMonthDays(date);
|
||||
var dateToSet = date.GetFirstDayOfMonth().AddDays(-dayBefore);
|
||||
for (var i = 7; i < children.Count; i++)
|
||||
{
|
||||
@@ -216,32 +224,44 @@ public class CalendarView : TemplatedControl
|
||||
cell.Content = day.Day.ToString(info);
|
||||
dateToSet = dateToSet.AddDays(1);
|
||||
}
|
||||
|
||||
FadeOutDayButtons();
|
||||
}
|
||||
|
||||
private void RefreshYearButtons()
|
||||
private void UpdateYearButtons()
|
||||
{
|
||||
if (_yearGrid is null) return;
|
||||
var mode = Mode;
|
||||
var contextDate = ContextDate;
|
||||
for (var i = 0; i < 12; i++)
|
||||
var contextDate = ContextCalendar;
|
||||
if (mode == CalendarViewMode.Century && contextDate.StartYear.HasValue)
|
||||
{
|
||||
var child = _yearGrid.Children[i] as CalendarYearButton;
|
||||
if (child is null) continue;
|
||||
switch (mode)
|
||||
var range = DateTimeHelper.GetCenturyViewRangeByYear(contextDate.StartYear.Value);
|
||||
int start = range.start-10;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
case CalendarViewMode.Month:
|
||||
child.SetValues(CalendarViewMode.Year, i);
|
||||
break;
|
||||
case CalendarViewMode.Year:
|
||||
child.SetValues(CalendarViewMode.Decade, year: ContextDate.Year / 10 * 10 + i - 1);
|
||||
break;
|
||||
case CalendarViewMode.Decade:
|
||||
var startYear = (ContextDate.Year / 10 + i - 1) * 10;
|
||||
var endYear = (ContextDate.Year / 10 + i - 1) * 10 + 10;
|
||||
child.SetValues(CalendarViewMode.Century, startYear: startYear, endYear: endYear);
|
||||
break;
|
||||
var child = _yearGrid.Children[i] as CalendarYearButton;
|
||||
child?.SetContext(CalendarViewMode.Century,
|
||||
new CalendarContext() { StartYear = start, EndYear = start + 10 });
|
||||
start+= 10;
|
||||
}
|
||||
}
|
||||
else if(mode == CalendarViewMode.Decade && contextDate.StartYear.HasValue)
|
||||
{
|
||||
var range = DateTimeHelper.GetDecadeViewRangeByYear(contextDate.StartYear.Value);
|
||||
int year = range.start - 1;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
var child = _yearGrid.Children[i] as CalendarYearButton;
|
||||
child?.SetContext(CalendarViewMode.Decade,
|
||||
new CalendarContext() { Year = year});
|
||||
year++;
|
||||
}
|
||||
}
|
||||
else if (mode == CalendarViewMode.Year)
|
||||
{
|
||||
for (var i = 0; i < 12; i++)
|
||||
{
|
||||
var child = _yearGrid.Children[i] as CalendarYearButton;
|
||||
child?.SetContext(CalendarViewMode.Year, new CalendarContext() { Month = i });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -251,7 +271,7 @@ public class CalendarView : TemplatedControl
|
||||
if (_monthGrid is null) return;
|
||||
var children = _monthGrid.Children;
|
||||
for (var i = 7; i < children.Count; i++)
|
||||
if (children[i] is CalendarDayButton { DataContext: DateTime d } button && d.Month != ContextDate.Month)
|
||||
if (children[i] is CalendarDayButton { DataContext: DateTime d } button && d.Month != ContextCalendar.Month)
|
||||
button.IsNotCurrentMonth = true;
|
||||
}
|
||||
|
||||
@@ -297,8 +317,9 @@ public class CalendarView : TemplatedControl
|
||||
/// <param name="e"></param>
|
||||
private void OnHeaderMonthButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty, ContextDate.Year);
|
||||
SetCurrentValue(ModeProperty, CalendarViewMode.Year);
|
||||
UpdateHeaderButtons();
|
||||
UpdateYearButtons();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -309,9 +330,12 @@ public class CalendarView : TemplatedControl
|
||||
private void OnHeaderYearButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_yearGrid is null) return;
|
||||
var decadeStart = ContextDate.Year / 10 * 10;
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty, decadeStart + "-" + (decadeStart + 10));
|
||||
SetCurrentValue(ModeProperty, CalendarViewMode.Decade);
|
||||
var range = DateTimeHelper.GetDecadeViewRangeByYear(ContextCalendar.Year!.Value);
|
||||
ContextCalendar.StartYear = range.start;
|
||||
ContextCalendar.EndYear = range.end;
|
||||
UpdateHeaderButtons();
|
||||
UpdateYearButtons();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -328,31 +352,66 @@ public class CalendarView : TemplatedControl
|
||||
{
|
||||
if (_yearGrid is null) return;
|
||||
var buttons = _yearGrid.Children.OfType<CalendarYearButton>().ToList();
|
||||
if (Mode == CalendarViewMode.Year)
|
||||
{
|
||||
Mode = CalendarViewMode.Month;
|
||||
if (e.Month is null) return;
|
||||
var day = MathHelpers.SafeClamp(e.Month.Value, 0,
|
||||
DateTime.DaysInMonth(ContextDate.Year!.Value, e.Month.Value + 1));
|
||||
ContextDate = new DateContext { Year = ContextDate.Year, Month = e.Month + 1, Day = day };
|
||||
}
|
||||
else if (Mode == CalendarViewMode.Decade)
|
||||
{
|
||||
Mode = CalendarViewMode.Year;
|
||||
for (var i = 0; i < 12; i++) buttons[i].SetValues(CalendarViewMode.Year, i);
|
||||
ContextDate = new DateContext { Year = e.Year!.Value, Month = null, Day = null };
|
||||
}
|
||||
else if (Mode == CalendarViewMode.Century)
|
||||
if (Mode == CalendarViewMode.Century)
|
||||
{
|
||||
Mode = CalendarViewMode.Decade;
|
||||
for (var i = 0; i < 12; i++)
|
||||
{
|
||||
if (e.StartYear is null || e.EndYear is null) continue;
|
||||
var year = e.StartYear.Value - 1 + i;
|
||||
buttons[i].SetValues(CalendarViewMode.Decade, year: year);
|
||||
}
|
||||
ContextCalendar.Year = null;
|
||||
ContextCalendar.StartYear = e.Context.StartYear;
|
||||
ContextCalendar.EndYear = e.Context.EndYear;
|
||||
}
|
||||
else if(Mode == CalendarViewMode.Decade)
|
||||
{
|
||||
Mode = CalendarViewMode.Year;
|
||||
ContextCalendar.Year = e.Context.Year;
|
||||
ContextCalendar.StartYear = e.Context.StartYear;
|
||||
ContextCalendar.EndYear = e.Context.EndYear;
|
||||
}
|
||||
else if (Mode == CalendarViewMode.Year)
|
||||
{
|
||||
Mode = CalendarViewMode.Month;
|
||||
ContextCalendar.StartYear = null;
|
||||
ContextCalendar.EndYear = null;
|
||||
// ContextCalendar.Year = e.Context.Year;
|
||||
ContextCalendar.Month = e.Context.Month;
|
||||
UpdateDayButtons();
|
||||
}
|
||||
else if (Mode == CalendarViewMode.Month)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
UpdateHeaderButtons();
|
||||
UpdateYearButtons();
|
||||
}
|
||||
|
||||
RefreshYearButtons();
|
||||
private void UpdateHeaderButtons()
|
||||
{
|
||||
if (this.Mode == CalendarViewMode.Century)
|
||||
{
|
||||
IsVisibleProperty.SetValue(true, _headerButton, _yearGrid);
|
||||
IsVisibleProperty.SetValue(false, _yearButton, _monthButton, _monthGrid);
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty, ContextCalendar.StartYear + "-" + ContextCalendar.EndYear);
|
||||
}
|
||||
else if (this.Mode == CalendarViewMode.Decade)
|
||||
{
|
||||
IsVisibleProperty.SetValue(true, _headerButton, _yearGrid);
|
||||
IsVisibleProperty.SetValue(false, _yearButton, _monthButton, _monthGrid);
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty, ContextCalendar.StartYear + "-" + ContextCalendar.EndYear);
|
||||
}
|
||||
else if (this.Mode == CalendarViewMode.Year)
|
||||
{
|
||||
IsVisibleProperty.SetValue(true, _headerButton, _yearGrid);
|
||||
IsVisibleProperty.SetValue(false, _yearButton, _monthButton, _monthGrid);
|
||||
_headerButton?.SetValue(ContentControl.ContentProperty, ContextCalendar.Year);
|
||||
}
|
||||
else if (this.Mode == CalendarViewMode.Month)
|
||||
{
|
||||
IsVisibleProperty.SetValue(false, _headerButton, _yearGrid);
|
||||
IsVisibleProperty.SetValue(true, _yearButton, _monthButton, _monthGrid);
|
||||
// _headerButton?.SetValue(ContentControl.ContentProperty, ContextCalendar.Year);
|
||||
_yearButton?.SetValue(ContentControl.ContentProperty, ContextCalendar.Year);
|
||||
_monthButton?.SetValue(ContentControl.ContentProperty,
|
||||
DateTimeHelper.GetCurrentDateTimeFormatInfo().AbbreviatedMonthNames[ContextCalendar.Month ?? 0]);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -22,13 +22,7 @@ public class CalendarYearButton : ContentControl
|
||||
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 CalendarContext CalendarContext { get; set; } = new ();
|
||||
|
||||
internal CalendarViewMode Mode { get; private set; }
|
||||
|
||||
@@ -37,30 +31,30 @@ public class CalendarYearButton : ContentControl
|
||||
add => AddHandler(ItemSelectedEvent, value);
|
||||
remove => RemoveHandler(ItemSelectedEvent, value);
|
||||
}
|
||||
|
||||
internal void SetValues(CalendarViewMode mode, int? month = null, int? year = null,
|
||||
int? startYear = null, int? endYear = null)
|
||||
|
||||
internal void SetContext(CalendarViewMode mode, CalendarContext context)
|
||||
{
|
||||
Debug.Assert(!(month is null && year is null && startYear is null && endYear is null));
|
||||
Mode = mode;
|
||||
Month = month ?? 0;
|
||||
Year = year ?? 0;
|
||||
StartYear = startYear ?? 0;
|
||||
EndYear = endYear ?? 0;
|
||||
CalendarContext = context.Clone();
|
||||
CalendarContext.Month = context.Month;
|
||||
CalendarContext.Year = context.Year;
|
||||
CalendarContext.StartYear = context.StartYear;
|
||||
CalendarContext.EndYear = context.EndYear;
|
||||
this.Mode = mode;
|
||||
Content = Mode switch
|
||||
{
|
||||
CalendarViewMode.Month => DateTimeHelper.GetCurrentDateTimeFormatInfo().AbbreviatedMonthNames[Month.Value],
|
||||
CalendarViewMode.Year => Year.ToString(),
|
||||
CalendarViewMode.Decade => StartYear + "-" + EndYear,
|
||||
CalendarViewMode.Century => StartYear + "-" + EndYear,
|
||||
CalendarViewMode.Year => DateTimeHelper.GetCurrentDateTimeFormatInfo().AbbreviatedMonthNames[ CalendarContext.Month ?? 0 ],
|
||||
CalendarViewMode.Decade => CalendarContext.Year?.ToString(),
|
||||
CalendarViewMode.Century => CalendarContext.StartYear + "-" + CalendarContext.EndYear,
|
||||
// CalendarViewMode.Century => CalendarContext.StartYear + "-" + CalendarContext.EndYear,
|
||||
_ => Content
|
||||
};
|
||||
IsEnabled = Content != null;
|
||||
}
|
||||
|
||||
protected override void OnPointerPressed(PointerPressedEventArgs e)
|
||||
{
|
||||
base.OnPointerPressed(e);
|
||||
RaiseEvent(new CalendarYearButtonEventArgs(Mode, Year, Month, StartYear, EndYear)
|
||||
RaiseEvent(new CalendarYearButtonEventArgs(Mode, this.CalendarContext.Clone())
|
||||
{ RoutedEvent = ItemSelectedEvent, Source = this });
|
||||
}
|
||||
}
|
||||
@@ -4,19 +4,13 @@ namespace Ursa.Controls;
|
||||
|
||||
public class CalendarYearButtonEventArgs: RoutedEventArgs
|
||||
{
|
||||
public int? Year { get; }
|
||||
public int? Month { get; }
|
||||
public int? StartYear { get; }
|
||||
public int? EndYear { get; }
|
||||
internal CalendarContext Context { get; }
|
||||
internal CalendarViewMode Mode { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
internal CalendarYearButtonEventArgs(CalendarViewMode mode, int? year, int? month, int? startYear, int? endYear )
|
||||
internal CalendarYearButtonEventArgs(CalendarViewMode mode, CalendarContext context)
|
||||
{
|
||||
Year = year;
|
||||
Month = month;
|
||||
StartYear = startYear;
|
||||
EndYear = endYear;
|
||||
Context = context;
|
||||
Mode = mode;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
namespace Ursa.Controls;
|
||||
|
||||
public class DateContext(int? year = null, int? month = null, int? day = null)
|
||||
{
|
||||
public int? Year = year;
|
||||
public int? Month = month;
|
||||
public int? Day = day;
|
||||
}
|
||||
@@ -42,4 +42,16 @@ internal static class DateTimeHelper
|
||||
{
|
||||
return d1.Ticks < d2.Ticks ? d2 : d1;
|
||||
}
|
||||
|
||||
public static (int start, int end) GetDecadeViewRangeByYear(int year)
|
||||
{
|
||||
int start = year / 10 * 10;
|
||||
return new ValueTuple<int, int>(start, start + 10);
|
||||
}
|
||||
|
||||
public static (int start, int end) GetCenturyViewRangeByYear(int year)
|
||||
{
|
||||
int start = year / 100 * 100;
|
||||
return new ValueTuple<int, int>(start, start + 100);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user