Add week numbers support to Calendar - #21981
Conversation
There was a problem hiding this comment.
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
IsWeekNumberVisibleandWeekNumberRulestyled properties toCalendar, and surfaced them onCalendarDatePicker. - Updated Fluent
CalendarItemtemplate to add a week-number header + column and a:hasweeknumberspseudo-class styling hook. - Added
DateTimeHelper.GetWeekOfYear(...)to compute week-of-year with an ISO fix forFirstFourDayWeek + 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.
There was a problem hiding this comment.
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 becauseWeekNumberRuleis already aCalendarWeekRuleenum. 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 withGrid.Rowstarting at 1 (rows 1..RowsPerMonth-1). Selecting the first label byGrid.GetRow(x) == 2skips 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);
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
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.
|
You can test this PR using the following package version. |
MrJul
left a comment
There was a problem hiding this comment.
Just a typo to fix, otherwise this looks good.
|
You can test this PR using the following package version. |
|
You can test this PR using the following package version. |
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)

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?
IsWeekNumberVisible="True".DynamicResouce: StringCalendarWeekNumberHeaderWeekNumberRuleusing theSystem.Globalization.CalendarWeekRule. UseWeekNumberRule="FirstFourDayWeek"in combination withFirstDayOfWeek="Monday"for ISO 8601 week numbering. Defaults to the current culture's rule.How was the solution implemented (if it's not obvious)?
API diff
ISO 8601 week number fix —
DateTimeHelper.GetWeekOfYear.NET's
Calendar.GetWeekOfYearwithFirstFourDayWeek+Mondayincorrectly 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:Checklist
Breaking changes
Obsoletions / Deprecations
Fixed issues
Fixes #7976
Closes #21311