Skip to content

Add week numbers support to Calendar - #21981

Merged
MrJul merged 15 commits into
AvaloniaUI:mainfrom
timunie:feat/CalendarWeekNumbers_2
Aug 20, 2026
Merged

Add week numbers support to Calendar#21981
MrJul merged 15 commits into
AvaloniaUI:mainfrom
timunie:feat/CalendarWeekNumbers_2

Conversation

@timunie

@timunie timunie commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator

What does the pull request do?

Note

This PR addesses the API review from #21311 . Decided to use a blank new branch since the new API proposal is easier to discuss that way.

Adds week number display to both Calendar and CalendarDatePicker in month view (Fluent and Simple themes).

This is the final result (using FluentTheme)
image

What is the current behavior?

Calendar and CalendarDatePicker only show day-of-week headers and date cells in month view. There is no way to display week numbers alongside the calendar grid.

What is the updated/expected behavior with this PR?

  • A new week-number column can be shown on the left side of the month grid by setting IsWeekNumberVisible="True".
  • The column header is configurable via DynamicResouce: StringCalendarWeekNumberHeader
  • The week numbering rule is configurable via WeekNumberRule using the System.Globalization.CalendarWeekRule. Use WeekNumberRule="FirstFourDayWeek" in combination with FirstDayOfWeek="Monday" for ISO 8601 week numbering. Defaults to the current culture's rule.
  • All properties are mirrored on CalendarDatePicker, where they propagate to the inner popup calendar.
  • In FluentTheme the calendar does not shrink when switching from month view to year/decade view. A new :hasweeknumbers pseudo-class on CalendarItem is used in the Fluent theme to hold the minimum width stable.

How was the solution implemented (if it's not obvious)?

API diff

// Avalonia.Controls.Calendar — 3 new properties
+public static readonly StyledProperty<bool> IsWeekNumberVisibleProperty;
+public bool IsWeekNumberVisible { get; set; }                       // default: false

+public static readonly StyledProperty<CalendarWeekNumberRule> WeekNumberRuleProperty;
+public CalendarWeekNumberRule WeekNumberRule { get; set; }          // default: current culture

// Avalonia.Controls.CalendarDatePicker — same 2 properties via AddOwner
+public static readonly StyledProperty<bool> IsWeekNumberVisibleProperty;
+public bool IsWeekNumberVisible { get; set; }

+public static readonly StyledProperty<CalendarWeekNumberRule> WeekNumberRuleProperty;
+public CalendarWeekNumberRule WeekNumberRule { get; set; }

// Avalonia.Controls.Primitives.CalendarItem — new pseudo-class, new Template part
-[PseudoClasses(":calendardisabled")]
+[PseudoClasses(":calendardisabled", ":hasweeknumbers")]
+[TemplatePart(PART_ElementWeekNumberLabels, typeof(Grid))]

ISO 8601 week number fix — DateTimeHelper.GetWeekOfYear

.NET's Calendar.GetWeekOfYear with FirstFourDayWeek + Monday incorrectly returns week 53 for late-December dates that ISO 8601 assigns to week 1 of the next year (e.g. 2018-12-31 → ISO week 1 of 2019). Added a helper mehtod to solve this:

public static int GetWeekOfYear(DateTime date, 
    CalendarWeekRule rule, 
    DayOfWeek firstDayOfWeek, 
    System.Globalization.Calendar calendar)
{
    // .NET's Calendar.GetWeekOfYear incorrectly returns week 53 for late-December dates
    // that ISO 8601 assigns to week 1 of the next year (e.g. 2018-12-31).
    if (rule == CalendarWeekRule.FirstFourDayWeek && firstDayOfWeek == DayOfWeek.Monday)
        return ISOWeek.GetWeekOfYear(date);

    return calendar.GetWeekOfYear(date, rule, firstDayOfWeek);
}

Checklist

  • Added unit tests (if possible)? -> Let me know if any more test is needed
  • Added XML documentation to any related classes?
  • Consider submitting a PR to https://github.com/AvaloniaUI/avalonia-docs with user documentation --> To be done when the PR is accepted

Breaking changes

Obsoletions / Deprecations

Fixed issues

Fixes #7976
Closes #21311

@timunie
timunie marked this pull request as draft August 14, 2026 11:23
@timunie
timunie requested review from MrJul and a lite review from Copilot August 14, 2026 11:23

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an alternative week-number API for Calendar / CalendarDatePicker and wires up Fluent theme visuals to display a week-number column in month view, including a week-of-year helper that uses ISOWeek for ISO-style rules.

Changes:

  • Added IsWeekNumberVisible and WeekNumberRule styled properties to Calendar, and surfaced them on CalendarDatePicker.
  • Updated Fluent CalendarItem template to add a week-number header + column and a :hasweeknumbers pseudo-class styling hook.
  • Added DateTimeHelper.GetWeekOfYear(...) to compute week-of-year with an ISO fix for FirstFourDayWeek + Monday.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/Avalonia.Themes.Fluent/Strings/InvariantResources.xaml Adds a Fluent resource key for the week-number header.
src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml Adds week-number header/column to the template and styles them via :hasweeknumbers.
src/Avalonia.Themes.Fluent/Controls/CalendarDatePicker.xaml Propagates week-number properties into the popup Calendar.
src/Avalonia.Themes.Fluent/Accents/FluentControlResources.xaml Adds a font-size resource for week-number labels.
src/Avalonia.Controls/CalendarDatePicker/CalendarDatePicker.Properties.cs Adds IsWeekNumberVisible and WeekNumberRule properties via AddOwner.
src/Avalonia.Controls/Calendar/DateTimeHelper.cs Adds GetWeekOfYear helper with ISOWeek fallback for ISO-style week numbering.
src/Avalonia.Controls/Calendar/CalendarItem.cs Populates and updates week-number label controls in month mode; sets :hasweeknumbers.
src/Avalonia.Controls/Calendar/Calendar.cs Introduces the new styled properties on Calendar.
samples/ControlCatalog/Pages/CalendarPage.xaml Adds a ControlCatalog sample demonstrating week numbers and header resource override.
samples/ControlCatalog/Pages/CalendarDatePickerPage.xaml Adds a ControlCatalog sample demonstrating week numbers on CalendarDatePicker.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/Avalonia.Controls/Calendar/Calendar.cs
Comment thread src/Avalonia.Controls/Calendar/Calendar.cs
Comment thread src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml Outdated
Comment thread src/Avalonia.Controls/Calendar/CalendarItem.cs Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Suppressed comments (4)

tests/Avalonia.Controls.UnitTests/CalendarTests.cs:601

  • After changing the rule, the test re-selects the label using Grid.GetRow(x) == 2, which doesn't match how the week-number labels are created (row 1 is the first week row).
            firstLabel = weekLabelsGrid.Children.OfType<ContentControl>().First(x => Grid.GetRow(x) == 2);

src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml:65

  • The header sub-Grid doesn't declare any ColumnDefinitions, but its children use Grid.Column=1/2 and the Rectangle uses Grid.ColumnSpan=3. Without explicit columns, all header content can end up laid out in a single column (overlapping) depending on Grid's fallback behavior.
                <Grid Grid.ColumnSpan="2" >

tests/Avalonia.Controls.UnitTests/CalendarTests.cs:462

  • This test name implies it verifies the default value comes from the current culture, but Assert.IsType<CalendarWeekRule>(calendar.WeekNumberRule) will always pass because WeekNumberRule is already a CalendarWeekRule enum. This doesn't validate the intended behavior.
        public void WeekNumberRule_Defaults_To_Culture_CalendarWeekRule()
        {
            var calendar = new Calendar();
            Assert.IsType<CalendarWeekRule>(calendar.WeekNumberRule);
        }

tests/Avalonia.Controls.UnitTests/CalendarTests.cs:591

  • CalendarItem.PopulateGrids() creates week-number label cells with Grid.Row starting at 1 (rows 1..RowsPerMonth-1). Selecting the first label by Grid.GetRow(x) == 2 skips the first week row and makes the assertion inconsistent with the production layout.

This issue also appears on line 601 of the same file.

            Assert.NotNull(weekLabelsGrid);
            var firstLabel = weekLabelsGrid.Children.OfType<ContentControl>().First(x => Grid.GetRow(x) == 2);
            Assert.Equal(1, firstLabel.Content);

@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0068334-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Comment thread src/Avalonia.Controls/Calendar/Calendar.cs
Comment thread src/Avalonia.Controls/Calendar/Calendar.cs
Comment thread src/Avalonia.Controls/Calendar/CalendarItem.cs Outdated
Comment thread src/Avalonia.Controls/Calendar/CalendarItem.cs Outdated
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0068348-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

since it is not part of the MonthGrid, it can leak into the year view. We solved this by updating IsVisible in code behind just like other template parts.

Moved the header into the panel to show / hide it together with the entire Grid.
@timunie
timunie marked this pull request as ready for review August 14, 2026 18:20
@timunie timunie added feature api-needs-review The PR adds new public APIs that should be reviewed. labels Aug 14, 2026
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0068354-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a typo to fix, otherwise this looks good.

Comment thread src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml Outdated
Comment thread src/Avalonia.Themes.Fluent/Controls/CalendarItem.xaml Outdated
Comment thread src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml Outdated
Comment thread src/Avalonia.Themes.Simple/Controls/CalendarItem.xaml Outdated
Comment thread src/Avalonia.Controls/Calendar/Calendar.cs Outdated
Comment thread src/Avalonia.Controls/Calendar/Calendar.cs Outdated
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0068551-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul changed the title Alternative API for Calendar with WeekNumbers Add week numbers support to Calendar Aug 20, 2026
@MrJul MrJul added api-approved The new public APIs have been approved. and removed api-needs-review The PR adds new public APIs that should be reviewed. labels Aug 20, 2026

@MrJul MrJul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@MrJul
MrJul enabled auto-merge August 20, 2026 07:35
@MrJul
MrJul added this pull request to the merge queue Aug 20, 2026
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.2.999-cibuild0068577-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

Merged via the queue into AvaloniaUI:main with commit 11376dd Aug 20, 2026
11 checks passed
@timunie
timunie deleted the feat/CalendarWeekNumbers_2 branch August 20, 2026 16:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api-approved The new public APIs have been approved. feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Calendar with week numbers

4 participants