feat: WIP.

This commit is contained in:
rabbitism
2024-06-19 22:16:28 +08:00
parent 0e73e8723d
commit b5e71f95c2
5 changed files with 284 additions and 222 deletions

View File

@@ -6,8 +6,6 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Ursa.Demo.Pages.DatePickerDemo">
<StackPanel Margin="20" HorizontalAlignment="Left">
<u:CalendarMonthView />
<u:CalendarYearView />
<u:CalendarView/>
</StackPanel>
</UserControl>

View File

@@ -4,7 +4,6 @@
xmlns:u="https://irihi.tech/ursa">
<Design.PreviewWith>
<StackPanel Margin="20" Spacing="5">
<u:CalendarMonthView />
<u:CalendarView />
</StackPanel>
</Design.PreviewWith>
@@ -119,144 +118,6 @@
<Setter Property="Cursor" Value="No" />
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:CalendarView}" TargetType="u:CalendarView">
<Setter Property="MinHeight" Value="300" />
<Setter Property="Template">
<ControlTemplate TargetType="u:CalendarView">
<Panel>
<Grid RowDefinitions="Auto, *">
<Grid Grid.Row="0" ColumnDefinitions="Auto, Auto,*, Auto, Auto">
<Button
Name="{x:Static u:CalendarView.PART_PreviousYearButton}"
Grid.Column="0"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemPreviousIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
<Button
Name="{x:Static u:CalendarView.PART_PreviousButton}"
Grid.Column="1"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemPreviousIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
<Grid Grid.Column="2" ColumnDefinitions="*, *">
<Button
Name="{x:Static u:CalendarView.PART_YearButton}"
Grid.Column="0"
HorizontalContentAlignment="Center"
Content="2024"
Foreground="{TemplateBinding Foreground}"
IsVisible="{TemplateBinding IsMonthMode}"
Theme="{DynamicResource BorderlessButton}" />
<Button
Name="{x:Static u:CalendarView.PART_MonthButton}"
Grid.Column="1"
HorizontalContentAlignment="Center"
Content="Apr"
Foreground="{TemplateBinding Foreground}"
IsVisible="{TemplateBinding IsMonthMode}"
Theme="{DynamicResource BorderlessButton}" />
<Button
Name="{x:Static u:CalendarView.PART_HeaderButton}"
Grid.Column="0"
Grid.ColumnSpan="2"
IsVisible="{TemplateBinding IsMonthMode, Converter={x:Static BoolConverters.Not}}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Content="2020-2030" />
</Grid>
<Button
Name="{x:Static u:CalendarView.PART_NextButton}"
Grid.Column="3"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemNextIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
<Button
Name="{x:Static u:CalendarView.PART_NextYearButton}"
Grid.Column="4"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemNextIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
</Grid>
<u:CalendarMonthView
Name="{x:Static u:CalendarView.PART_MonthView}"
Grid.Row="1"
VerticalAlignment="Top"
IsVisible="{TemplateBinding IsMonthMode}" />
<u:CalendarYearView
Name="{x:Static u:CalendarView.PART_YearView}"
Grid.Row="1"
Width="{Binding #PART_MonthView.Bounds.Width}"
Height="{Binding #PART_MonthView.Bounds.Height}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
IsVisible="{TemplateBinding IsMonthMode,
Converter={x:Static BoolConverters.Not}}" />
</Grid>
</Panel>
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:CalendarMonthView}" TargetType="u:CalendarMonthView">
<Setter Property="Template">
<ControlTemplate>
<Grid
Name="{x:Static u:CalendarMonthView.PART_Grid}"
ColumnDefinitions="*, *, *, *, *, *, *"
RowDefinitions="*, Auto, *, *, *, *, *, *">
<Rectangle
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="7"
Height="1"
Margin="8,8,8,0"
HorizontalAlignment="Stretch"
Fill="{DynamicResource SemiGrey2}" />
</Grid>
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:CalendarYearView}" TargetType="u:CalendarYearView">
<Setter Property="Template">
<ControlTemplate>
<Grid
Name="{x:Static u:CalendarYearView.PART_Grid}"
ColumnDefinitions="*, *, *"
RowDefinitions="*, *, *, *" />
</ControlTemplate>
</Setter>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:CalendarYearButton}" TargetType="u:CalendarYearButton">
<Setter Property="MinWidth" Value="32" />
<Setter Property="MinHeight" Value="32" />
@@ -298,4 +159,119 @@
</Style>
</Style>
</ControlTheme>
<ControlTheme x:Key="{x:Type u:CalendarView}" TargetType="u:CalendarView">
<Setter Property="MinHeight" Value="300" />
<Setter Property="Template">
<ControlTemplate TargetType="u:CalendarView">
<Panel>
<Grid RowDefinitions="Auto, *">
<Grid Grid.Row="0" ColumnDefinitions="Auto, Auto,*, Auto, Auto">
<Button
Name="{x:Static u:CalendarView.PART_PreviousYearButton}"
Grid.Column="0"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemPreviousIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
<Button
Name="{x:Static u:CalendarView.PART_PreviousButton}"
Grid.Column="1"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemPreviousIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
<Grid Grid.Column="2" ColumnDefinitions="*, *">
<Button
Name="{x:Static u:CalendarView.PART_YearButton}"
Grid.Column="0"
HorizontalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}" />
<Button
Name="{x:Static u:CalendarView.PART_MonthButton}"
Grid.Column="1"
HorizontalContentAlignment="Center"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}" />
<Button
Name="{x:Static u:CalendarView.PART_HeaderButton}"
Grid.Column="0"
IsVisible="True"
Grid.ColumnSpan="2"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center" />
</Grid>
<Button
Name="{x:Static u:CalendarView.PART_NextButton}"
Grid.Column="3"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemNextIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
<Button
Name="{x:Static u:CalendarView.PART_NextYearButton}"
Grid.Column="4"
HorizontalContentAlignment="Left"
Foreground="{TemplateBinding Foreground}"
Theme="{DynamicResource BorderlessButton}">
<PathIcon
Width="12"
Height="12"
Data="{DynamicResource CalendarItemNextIconGlyph}"
Foreground="{DynamicResource CalendarItemIconForeground}" />
</Button>
</Grid>
<Grid
Name="{x:Static u:CalendarView.PART_MonthGrid}"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ColumnDefinitions="*, *, *, *, *, *, *"
RowDefinitions="*, Auto, *, *, *, *, *, *" />
<Grid
Name="{x:Static u:CalendarView.PART_YearGrid}"
Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ColumnDefinitions="*, *, *"
RowDefinitions="*, *, *, *" />
</Grid>
</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>

View File

@@ -8,6 +8,7 @@ using Avalonia.Layout;
namespace Ursa.Controls;
/*
/// <summary>
/// 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.
@@ -226,4 +227,6 @@ public class CalendarMonthView : TemplatedControl
button.IsInRange = false;
}
}
}
}
*/

View File

@@ -1,14 +1,13 @@
using System.Globalization;
using System.Reflection;
using System.Diagnostics;
using System.Globalization;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Media.TextFormatting;
using Irihi.Avalonia.Shared.Helpers;
using Calendar = System.Globalization.Calendar;
namespace Ursa.Controls;
@@ -19,11 +18,10 @@ namespace Ursa.Controls;
[TemplatePart(PART_YearButton, typeof(Button))]
[TemplatePart(PART_MonthButton, typeof(Button))]
[TemplatePart(PART_HeaderButton, typeof(Button))]
[TemplatePart(PART_MonthView, typeof(CalendarMonthView))]
[TemplatePart(PART_YearView, typeof(CalendarYearView))]
[TemplatePart(PART_MonthGrid, typeof(Grid))]
[TemplatePart(PART_YearGrid, typeof(Grid))]
public class CalendarView: TemplatedControl
[PseudoClasses(PC_Month)]
public class CalendarView : TemplatedControl
{
public const string PART_NextYearButton = "PART_NextYearButton";
public const string PART_PreviousYearButton = "PART_PreviousYearButton";
@@ -31,51 +29,79 @@ public class CalendarView: TemplatedControl
public const string PART_PreviousButton = "PART_PreviousButton";
public const string PART_YearButton = "PART_YearButton";
public const string PART_MonthButton = "PART_MonthButton";
public const string PART_MonthView = "PART_MonthView";
public const string PART_YearView = "PART_YearView";
public const string PART_HeaderButton = "PART_HeaderButton";
public const string PART_MonthGrid = "PART_MonthGrid";
public const string PART_YearGrid = "PART_YearGried";
public const string PART_YearGrid = "PART_YearGrid";
public const string PC_Month = ":month";
private const string ShortestDayName = "ShortestDayName";
private readonly System.Globalization.Calendar _calendar = new GregorianCalendar();
internal CalendarViewMode Mode;
//private CalendarMonthView? _monthView;
//private CalendarYearView? _yearView;
private Grid? _monthGrid;
private Grid? _yearGrid;
// Year button only shows the year in month mode.
private Button? _yearButton;
// Month button only shows the month in month mode.
private Button? _monthButton;
// Header button shows year in year mode, and year range in higher mode.
private Button? _headerButton;
public DateContext ContextDate { get; set; } = new DateContext();
public event EventHandler<CalendarDayButtonEventArgs>? OnDateSelected;
public event EventHandler<CalendarDayButtonEventArgs>? OnDatePreviewed;
internal static readonly DirectProperty<CalendarView, CalendarViewMode> ModeProperty =
AvaloniaProperty.RegisterDirect<CalendarView, CalendarViewMode>(
nameof(Mode), o => o.Mode, (o, v) => o.Mode = v, unsetValue: CalendarViewMode.Month);
public static readonly StyledProperty<bool> IsTodayHighlightedProperty =
DatePickerBase.IsTodayHighlightedProperty.AddOwner<CalendarView>();
public static readonly StyledProperty<DayOfWeek> FirstDayOfWeekProperty =
DatePickerBase.FirstDayOfWeekProperty.AddOwner<CalendarView>();
private readonly Calendar _calendar = new GregorianCalendar();
// Header button shows year in year mode, and year range in higher mode.
private Button? _headerButton;
private CalendarViewMode _mode;
// Month button only shows the month in month mode.
private Button? _monthButton;
private Grid? _monthGrid;
// Year button only shows the year in month mode.
private Button? _yearButton;
private Grid? _yearGrid;
static CalendarView()
{
FirstDayOfWeekProperty.Changed.AddClassHandler<CalendarView, DayOfWeek>((view, args) =>
view.OnFirstDayOfWeekChanged(args));
ModeProperty.Changed.AddClassHandler<CalendarView, CalendarViewMode>((view, args) =>
{
view.PseudoClasses.Set(PC_Month, args.NewValue.Value == CalendarViewMode.Month);
Debug.WriteLine(args.NewValue.Value);
});
}
internal CalendarViewMode Mode
{
get => _mode;
set => SetAndRaise(ModeProperty, ref _mode, value);
}
public DateContext ContextDate { get; set; } = new();
public bool IsTodayHighlighted
{
get => GetValue(IsTodayHighlightedProperty);
set => SetValue(IsTodayHighlightedProperty, value);
}
public static readonly StyledProperty<DayOfWeek> FirstDayOfWeekProperty =
DatePickerBase.FirstDayOfWeekProperty.AddOwner<CalendarView>();
public DayOfWeek FirstDayOfWeek
{
get => GetValue(FirstDayOfWeekProperty);
set => SetValue(FirstDayOfWeekProperty, value);
}
public event EventHandler<CalendarDayButtonEventArgs>? OnDateSelected;
public event EventHandler<CalendarDayButtonEventArgs>? OnDatePreviewed;
private void OnFirstDayOfWeekChanged(AvaloniaPropertyChangedEventArgs<DayOfWeek> args)
{
UpdateMonthViewHeader(args.NewValue.Value);
RefreshDayButtons();
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
base.OnApplyTemplate(e);
@@ -83,7 +109,7 @@ public class CalendarView: TemplatedControl
Button.ClickEvent.RemoveHandler(OnHeaderYearButtonClick, _yearButton);
Button.ClickEvent.RemoveHandler(OnHeaderMonthButtonClick, _monthButton);
Button.ClickEvent.RemoveHandler(OnHeaderButtonClick, _headerButton);
_monthGrid = e.NameScope.Find<Grid>(PART_MonthGrid);
_yearGrid = e.NameScope.Find<Grid>(PART_YearGrid);
_yearButton = e.NameScope.Find<Button>(PART_YearButton);
@@ -94,30 +120,40 @@ 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);
PseudoClasses.Set(PC_Month, Mode == CalendarViewMode.Month);
GenerateGridElements();
RefreshDayButtons();
RefreshYearButtons();
}
/// <summary>
/// Rule:
/// Rule:
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnHeaderButtonClick(object sender, RoutedEventArgs e)
{
if (Mode == CalendarViewMode.Month)
{
throw new NotImplementedException();
}
// Header button should be hidden in Month mode.
if (Mode == CalendarViewMode.Month) return;
if (Mode == CalendarViewMode.Year)
{
Mode = CalendarViewMode.Decade;
RefreshYearButtons();
return;
}
if(Mode == CalendarViewMode.Decade)
{
Mode = CalendarViewMode.Century;
RefreshYearButtons();
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.
/// </summary>
private void GenerateGridElements()
{
@@ -147,8 +183,9 @@ public class CalendarView: TemplatedControl
cell.AddHandler(CalendarDayButton.DatePreviewedEvent, OnCellDatePreviewed);
children.Add(cell);
}
_monthGrid?.Children.AddRange(children);
// Generate month/year buttons.
for (var i = 0; i < 12; i++)
{
@@ -160,14 +197,16 @@ public class CalendarView: TemplatedControl
}
}
private void RefreshButtons(DateTime date)
private void RefreshDayButtons()
{
if (_monthGrid is null) return;
var children = _monthGrid.Children;
var info = DateTimeHelper.GetCurrentDateTimeFormatInfo();
var dayBefore = PreviousMonthDays(date);
var date = new DateTime(ContextDate.Year.Value, ContextDate.Month.Value, ContextDate.Day.Value);
var dayBefore =
PreviousMonthDays(date);
var dateToSet = date.GetFirstDayOfMonth().AddDays(-dayBefore);
for (var i = 8; i < children.Count; i++)
for (var i = 7; i < children.Count; i++)
{
var day = dateToSet;
var cell = children[i] as CalendarDayButton;
@@ -180,16 +219,58 @@ public class CalendarView: TemplatedControl
FadeOutDayButtons();
}
private void RefreshYearButtons()
{
if (_yearGrid is null) return;
var mode = Mode;
var contextDate = ContextDate;
for (var i = 0; i < 12; i++)
{
var child = _yearGrid.Children[i] as CalendarYearButton;
if (child is null) continue;
switch (mode)
{
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;
}
}
}
private void FadeOutDayButtons()
{
if (_monthGrid is null) return;
var children = _monthGrid.Children;
for (var i = 8; i < children.Count; i++)
for (var i = 7; i < children.Count; i++)
if (children[i] is CalendarDayButton { DataContext: DateTime d } button && d.Month != ContextDate.Month)
button.IsNotCurrentMonth = true;
}
private void UpdateMonthViewHeader(DayOfWeek day)
{
var dayOfWeek = (int)day;
var info = DateTimeHelper.GetCurrentDateTimeFormatInfo();
var texts = _monthGrid?.Children.Where(a => a is TextBlock { Tag: ShortestDayName }).ToList();
if (texts is not null)
for (var i = 0; i < 7; i++)
{
var d = (dayOfWeek + i) % DateTimeHelper.NumberOfDaysPerWeek;
texts[i].SetValue(TextBlock.TextProperty, info.ShortestDayNames[d]);
texts[i].SetValue(HorizontalAlignmentProperty, HorizontalAlignment.Center);
texts[i].SetValue(Grid.RowProperty, 0);
texts[i].SetValue(Grid.ColumnProperty, i);
}
}
private int PreviousMonthDays(DateTime date)
{
var firstDay = date.GetFirstDayOfMonth();
@@ -198,7 +279,7 @@ public class CalendarView: TemplatedControl
var i = (dayOfWeek - firstDayOfWeek + DateTimeHelper.NumberOfDaysPerWeek) % DateTimeHelper.NumberOfDaysPerWeek;
return i == 0 ? DateTimeHelper.NumberOfDaysPerWeek : i;
}
private void OnCellDatePreviewed(object sender, CalendarDayButtonEventArgs e)
{
OnDatePreviewed?.Invoke(sender, e);
@@ -210,66 +291,68 @@ public class CalendarView: TemplatedControl
}
/// <summary>
/// Click on Month Header button. Calendar switch from month mode to year mode.
/// Click on Month Header button. Calendar switch from month mode to year mode.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnHeaderMonthButtonClick(object sender, RoutedEventArgs e)
{
_headerButton?.SetValue(ContentControl.ContentProperty, ContextDate.Year);
Mode = CalendarViewMode.Year;
IsVisibleProperty.SetValue(true, _yearGrid);
IsVisibleProperty.SetValue(false, _monthGrid);
SetCurrentValue(ModeProperty, CalendarViewMode.Year);
}
/// <summary>
/// Click on Year Header button. Calendar switch from month mode to decade mode.
/// Click on Year Header button. Calendar switch from month mode to decade mode.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnHeaderYearButtonClick(object sender, RoutedEventArgs e)
{
if (_yearGrid is null) return;
int? decadeStart = ContextDate.Year / 10 * 10;
_headerButton?.SetValue(ContentControl.ContentProperty,
decadeStart + "-" + (decadeStart + 10));
Mode = CalendarViewMode.Decade;
IsVisibleProperty.SetValue(true, _yearGrid);
IsVisibleProperty.SetValue(false, _monthGrid);
var decadeStart = ContextDate.Year / 10 * 10;
_headerButton?.SetValue(ContentControl.ContentProperty, decadeStart + "-" + (decadeStart + 10));
SetCurrentValue(ModeProperty, CalendarViewMode.Decade);
}
/// <summary>
/// Click on CalendarYearButton in YearView.
/// Mode switch rules are:
/// 1. Month -> Not supported, buttons are hidden.
/// 2. Year -> Month: Set the date to the selected year and switch to Month mode.
/// 3. Decade -> Year: Set the date to the selected year and switch to Year mode.
/// 4. Century -> Decade: Set the date to the selected year and switch to Decade mode.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void OnYearItemSelected(object sender, CalendarYearButtonEventArgs e)
{
if (_yearGrid is null) return;
var buttons = _yearGrid.Children.OfType<CalendarYearButton>().ToList();
if (e.Mode == CalendarViewMode.Year)
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 };
Mode = CalendarViewMode.Month;
}
else if (e.Mode == CalendarViewMode.Decade)
else if (Mode == CalendarViewMode.Decade)
{
// Set CalendarYearView to Month mode
for (var i = 0; i < 12; i++)
{
buttons[i].SetValues(CalendarViewMode.Month, month: i);
}
ContextDate = new DateContext() { Year = e.Year!.Value, Month = ContextDate.Month, Day = null };
Mode = CalendarViewMode.Month;
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 (e.Mode == CalendarViewMode.Century)
else if (Mode == CalendarViewMode.Century)
{
// Set CalendarYearView to Year mode
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.Year, year: year);
buttons[i].SetValues(CalendarViewMode.Decade, year: year);
}
Mode = CalendarViewMode.Year;
}
RefreshYearButtons();
}
}
}

View File

@@ -6,6 +6,7 @@ using Irihi.Avalonia.Shared.Helpers;
namespace Ursa.Controls;
/*
/// <summary>
/// Three modes:
/// 1. show 12 months in a year
@@ -116,4 +117,5 @@ public class CalendarYearView: TemplatedControl
Mode = mode;
RefreshButtons();
}
}
}
*/