Browse Source

Improvements to Weeknumber behavior

timunie 4 months ago
parent
commit
64feeb44c4
  1. 5
      samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml
  2. 2
      src/Avalonia.Controls/Calendar/Calendar.cs
  3. 4
      src/Avalonia.Controls/Calendar/CalendarItem.cs
  4. 50
      src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.Properties.cs
  5. 5
      src/Avalonia.Themes.Fluent/Controls/CalendarDatePicker.xaml
  6. 10
      src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml
  7. 5
      src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml
  8. 7
      src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml

5
samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml

@ -49,6 +49,11 @@
<TextBlock Text="Validation Example"/>
<CalendarDatePicker SelectedDate="{CompiledBinding ValidatedDateExample, Mode=TwoWay}"/>
<TextBlock Text="Show WeekNumbers" />
<CalendarDatePicker ShowWeekNumbers="True"
FirstDayOfWeek="Monday"
WeekNumberRule="FirstFourDayWeek" />
</StackPanel>
</StackPanel>

2
src/Avalonia.Controls/Calendar/Calendar.cs

@ -390,7 +390,7 @@ namespace Avalonia.Controls
/// Defines the <see cref="WeekNumberHeader"/> property.
/// </summary>
public static readonly StyledProperty<object?> WeekNumberHeaderProperty =
AvaloniaProperty.Register<Calendar, object?>(nameof(WeekNumberHeader));
AvaloniaProperty.Register<Calendar, object?>(nameof(WeekNumberHeader), "#");
/// <summary>
/// Gets or sets the content displayed in the week-number column header cell.

4
src/Avalonia.Controls/Calendar/CalendarItem.cs

@ -24,7 +24,7 @@ namespace Avalonia.Controls.Primitives
[TemplatePart(PART_ElementNextButton, typeof(Button))]
[TemplatePart(PART_ElementPreviousButton, typeof(Button))]
[TemplatePart(PART_ElementYearView, typeof(Grid))]
[PseudoClasses(":calendardisabled")]
[PseudoClasses(":calendardisabled", ":showweeknumbers")]
public sealed class CalendarItem : TemplatedControl
{
/// <summary>
@ -632,6 +632,8 @@ namespace Avalonia.Controls.Primitives
var rule = Owner?.WeekNumberRule ?? DateTimeHelper.GetCurrentDateFormat().CalendarWeekRule;
var firstDayOfWeek = Owner?.FirstDayOfWeek ?? DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek;
PseudoClasses.Set(":showweeknumbers", show);
for (int i = 0; i < _weekNumberLabels.Length; i++)
{
DateTime firstDayOfRow = _calendar.AddDays(firstDateDisplayed, i * NumberOfDaysPerWeek);

50
src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.Properties.cs

@ -1,4 +1,5 @@
using System;
using System.Globalization;
using Avalonia.Controls.Primitives;
using Avalonia.Data;
using Avalonia.Layout;
@ -140,6 +141,24 @@ namespace Avalonia.Controls
public static readonly StyledProperty<VerticalAlignment> VerticalContentAlignmentProperty =
ContentControl.VerticalContentAlignmentProperty.AddOwner<CalendarDatePicker>();
/// <summary>
/// Defines the <see cref="ShowWeekNumbers"/> property.
/// </summary>
public static readonly StyledProperty<bool> ShowWeekNumbersProperty =
Calendar.ShowWeekNumbersProperty.AddOwner<CalendarDatePicker>();
/// <summary>
/// Defines the <see cref="WeekNumberRule"/> property.
/// </summary>
public static readonly StyledProperty<CalendarWeekRule> WeekNumberRuleProperty =
Calendar.WeekNumberRuleProperty.AddOwner<CalendarDatePicker>();
/// <summary>
/// Defines the <see cref="WeekNumberHeader"/> property.
/// </summary>
public static readonly StyledProperty<object?> WeekNumberHeaderProperty =
Calendar.WeekNumberHeaderProperty.AddOwner<CalendarDatePicker>();
/// <summary>
/// Gets a collection of dates that are marked as not selectable.
/// </summary>
@ -358,5 +377,36 @@ namespace Avalonia.Controls
get => GetValue(VerticalContentAlignmentProperty);
set => SetValue(VerticalContentAlignmentProperty, value);
}
/// <summary>
/// Gets or sets a value indicating whether week numbers are shown in the month view
/// of the drop-down <see cref="Calendar"/>.
/// </summary>
public bool ShowWeekNumbers
{
get => GetValue(ShowWeekNumbersProperty);
set => SetValue(ShowWeekNumbersProperty, value);
}
/// <summary>
/// Gets or sets the rule used to determine the first week of the year for week number display.
/// The default is taken from the current culture.
/// </summary>
public CalendarWeekRule WeekNumberRule
{
get => GetValue(WeekNumberRuleProperty);
set => SetValue(WeekNumberRuleProperty, value);
}
/// <summary>
/// Gets or sets the content displayed in the week-number column header cell of the drop-down
/// <see cref="Calendar"/>. Set to a localized string such as <c>"CW"</c>, <c>"KW"</c>,
/// or <c>"Wk"</c> to give users context. Defaults to <c>null</c> (blank).
/// </summary>
public object? WeekNumberHeader
{
get => GetValue(WeekNumberHeaderProperty);
set => SetValue(WeekNumberHeaderProperty, value);
}
}
}

5
src/Avalonia.Themes.Fluent/Controls/CalendarDatePicker.xaml

@ -133,7 +133,10 @@
SelectedDate="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedDate, Mode=TwoWay}"
DisplayDate="{TemplateBinding DisplayDate}"
DisplayDateStart="{TemplateBinding DisplayDateStart}"
DisplayDateEnd="{TemplateBinding DisplayDateEnd}" />
DisplayDateEnd="{TemplateBinding DisplayDateEnd}"
ShowWeekNumbers="{TemplateBinding ShowWeekNumbers}"
WeekNumberRule="{TemplateBinding WeekNumberRule}"
WeekNumberHeader="{TemplateBinding WeekNumberHeader}" />
</Popup>
</Grid>
</Panel>

10
src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml

@ -73,9 +73,10 @@
<!-- To keep calendar from resizing when switching DisplayMode
In WinUI Min-Width from TemplateSettings
basically...MinWidth of DayItem = 40, 40 * 7 = 280 + margins/padding = ~294
With week numbers: 40 * 8 = 320 + margins/padding = ~334 (see :showweeknumbers style below)
Viewport height is set from # of rows displayed (2-8) in Month mode, = ~290 for 6 weeks (+ day names)
-->
<Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch" RowDefinitions="40,*" MinWidth="294">
<Grid x:Name="LayoutRoot" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" RowDefinitions="40,*" MinWidth="294">
<Grid ColumnDefinitions="5*,*,*">
<Button Name="PART_HeaderButton"
Theme="{StaticResource FluentCalendarButton}"
@ -159,5 +160,12 @@
<Style Selector="^ /template/ Button:pressed > Path">
<Setter Property="Stroke" Value="{DynamicResource CalendarViewNavigationButtonForegroundPressed}" />
</Style>
<!-- When week numbers are visible, the MonthView gains an extra 40px column.
Increase the LayoutRoot MinWidth to prevent the calendar from shrinking
when switching to year/decade view (which does not have that extra column).
334 = 40 (week-number col) + 294 (7 day-cols + margins/padding) -->
<Style Selector="^:showweeknumbers /template/ Grid#LayoutRoot">
<Setter Property="MinWidth" Value="334" />
</Style>
</ControlTheme>
</ResourceDictionary>

5
src/Avalonia.Themes.Simple/Controls/CalendarDatePicker.xaml

@ -128,7 +128,10 @@
FirstDayOfWeek="{TemplateBinding FirstDayOfWeek}"
IsTodayHighlighted="{TemplateBinding IsTodayHighlighted}"
SelectedDate="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedDate,
Mode=TwoWay}" />
Mode=TwoWay}"
ShowWeekNumbers="{TemplateBinding ShowWeekNumbers}"
WeekNumberRule="{TemplateBinding WeekNumberRule}"
WeekNumberHeader="{TemplateBinding WeekNumberHeader}" />
</Popup>
</Grid>
</ControlTemplate>

7
src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml

@ -176,5 +176,12 @@
<Style Selector="^:calendardisabled /template/ Rectangle#DisabledVisual">
<Setter Property="IsVisible" Value="True" />
</Style>
<!-- When week numbers are visible the MonthView is wider than the YearView.
Lock CalendarItem's own MinWidth so the size stays stable when switching
between month and year/decade views.
37px per CalendarButton × 4 cols = 148 + the week-number column (~30px) -->
<Style Selector="^:showweeknumbers">
<Setter Property="MinWidth" Value="200" />
</Style>
</ControlTheme>
</ResourceDictionary>

Loading…
Cancel
Save