Browse Source
Implement VerticalContentAlignment for DatePicker and TimePicker (#21464 )
* Add VerticalContentAlignment property to DatePicker and TimePicker
This change registers VerticalContentAlignmentProperty as a
StyledProperty using ContentControl's property as the owner for both
DatePicker and TimePicker controls to maintain framework consistency.
Basic xUnit v3 unit tests are introduced to validate property
round-trips (Top, Center, Bottom, Stretch) and to ensure the default
value correctly resolves to Stretch. This establishes the necessary
C# infrastructure before modifying the control templates.
Part of #21211 : implment fluent theme layout
* Fix VerticalContentAlignment bindings and integration tests
- Bind internal grids to VerticalContentAlignment in Fluent and Simple
themes for DatePicker and TimePicker controls.
- Add comprehensive integration tests using mocked NameScopes in
DatePickerTests and TimePickerTests to verify visual propagation.
- Validate visual layout correctness using the ControlCatalog app.
Closes AvaloniaUI#21211
* Remove tautological tests
---------
Co-authored-by: Martim Claudino <martimffclaudino@tecnico.ulisboa.pt>
Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
pull/22024/head
JoaoCruz
1 month ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with
72 additions and
4 deletions
src/Avalonia.Controls/DateTimePickers/DatePicker.cs
src/Avalonia.Controls/DateTimePickers/TimePicker.cs
src/Avalonia.Themes.Fluent/Controls/DatePicker.xaml
src/Avalonia.Themes.Fluent/Controls/TimePicker.xaml
src/Avalonia.Themes.Simple/Controls/DatePicker.xaml
src/Avalonia.Themes.Simple/Controls/TimePicker.xaml
tests/Avalonia.Controls.UnitTests/DatePickerTests.cs
tests/Avalonia.Controls.UnitTests/TimePickerTests.cs
@ -75,6 +75,21 @@ namespace Avalonia.Controls
public static readonly StyledProperty < bool > YearVisibleProperty =
AvaloniaProperty . Register < DatePicker , bool > ( nameof ( YearVisible ) , true ) ;
/// <summary>
/// Defines the <see cref="VerticalContentAlignment"/> property.
/// </summary>
public static readonly StyledProperty < VerticalAlignment > VerticalContentAlignmentProperty =
ContentControl . VerticalContentAlignmentProperty . AddOwner < DatePicker > ( ) ;
/// <summary>
/// Gets or sets the vertical alignment of the content within the control.
/// </summary>
public VerticalAlignment VerticalContentAlignment
{
get = > GetValue ( VerticalContentAlignmentProperty ) ;
set = > SetValue ( VerticalContentAlignmentProperty , value ) ;
}
/// <summary>
/// Defines the <see cref="SelectedDate"/> Property
/// </summary>
@ -50,6 +50,20 @@ namespace Avalonia.Controls
public static readonly StyledProperty < string > ClockIdentifierProperty =
AvaloniaProperty . Register < TimePicker , string > ( nameof ( ClockIdentifier ) , "12HourClock" , coerce : CoerceClockIdentifier ) ;
/// <summary>
/// Defines the <see cref="VerticalContentAlignment"/> property.
/// </summary>
public static readonly StyledProperty < VerticalAlignment > VerticalContentAlignmentProperty =
ContentControl . VerticalContentAlignmentProperty . AddOwner < TimePicker > ( ) ;
/// <summary>
/// Gets or sets the vertical alignment of the content within the control.
/// </summary>
public VerticalAlignment VerticalContentAlignment
{
get = > GetValue ( VerticalContentAlignmentProperty ) ;
set = > SetValue ( VerticalContentAlignmentProperty , value ) ;
}
/// <summary>
/// Defines the <see cref="UseSeconds"/> property
/// </summary>
@ -98,7 +98,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
TemplatedControl.IsTemplateFocusTarget="True">
<Grid Name="PART_ButtonContentGrid" ColumnDefinitions="78*,Auto,132*,Auto,78*">
<Grid Name="PART_ButtonContentGrid" ColumnDefinitions="78*,Auto,132*,Auto,78*" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" >
<TextBlock Name="PART_DayTextBlock" Text="{DynamicResource StringDatePickerDayText}" HorizontalAlignment="Center"
Padding="{DynamicResource DatePickerHostPadding}" />
<TextBlock Name="PART_MonthTextBlock" Text="{DynamicResource StringDatePickerMonthText}" TextAlignment="Left"
@ -97,7 +97,7 @@
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid Name="PART_FlyoutButtonContentGrid">
<Grid Name="PART_FlyoutButtonContentGrid" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" >
<!--Ignore col defs here, set in code-->
<Border x:Name="PART_FirstPickerHost"
Grid.Column="0"
@ -106,7 +106,8 @@
TemplatedControl.IsTemplateFocusTarget="True"
Theme="{StaticResource SimpleDatePickerFlyoutButton}">
<Grid Name="PART_ButtonContentGrid"
ColumnDefinitions="78*,Auto,132*,Auto,78*">
ColumnDefinitions="78*,Auto,132*,Auto,78*"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<TextBlock Name="PART_DayTextBlock"
Padding="{DynamicResource DatePickerHostPadding}"
HorizontalAlignment="Center"
@ -103,7 +103,7 @@
IsEnabled="{TemplateBinding IsEnabled}"
Theme="{StaticResource SimpleTimePickerFlyoutButton}">
<Grid Name="PART_FlyoutButtonContentGrid">
<Grid Name="PART_FlyoutButtonContentGrid" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" >
<!-- Ignore col defs here, set in code -->
<Border x:Name="PART_FirstPickerHost"
Grid.Column="0"
@ -13,6 +13,7 @@ using Avalonia.Platform;
using Avalonia.Threading ;
using Avalonia.UnitTests ;
using Avalonia.VisualTree ;
using Avalonia.Layout ;
using Moq ;
using Xunit ;
@ -371,6 +372,24 @@ namespace Avalonia.Controls.UnitTests
} ) ;
}
[Theory]
[InlineData(Avalonia.Layout.VerticalAlignment.Top)]
[InlineData(Avalonia.Layout.VerticalAlignment.Center)]
[InlineData(Avalonia.Layout.VerticalAlignment.Bottom)]
[InlineData(Avalonia.Layout.VerticalAlignment.Stretch)]
public void VerticalContentAlignment_RoundTrips ( Avalonia . Layout . VerticalAlignment value )
{
var datePicker = new DatePicker { VerticalContentAlignment = value } ;
Assert . Equal ( value , datePicker . VerticalContentAlignment ) ;
}
[Fact]
public void VerticalContentAlignment_Default_Is_Stretch ( )
{
var datePicker = new DatePicker ( ) ;
Assert . Equal ( Avalonia . Layout . VerticalAlignment . Stretch , datePicker . VerticalContentAlignment ) ;
}
private static IControlTemplate CreatePickerTemplate ( )
{
return new FuncControlTemplate ( ( _ , scope ) = >
@ -11,6 +11,7 @@ using Avalonia.Platform;
using Avalonia.Threading ;
using Avalonia.UnitTests ;
using Avalonia.VisualTree ;
using Avalonia.Layout ;
using Moq ;
using Xunit ;
@ -466,5 +467,23 @@ namespace Avalonia.Controls.UnitTests
return contentPanel ;
} ) ;
}
[Theory]
[InlineData(Avalonia.Layout.VerticalAlignment.Top)]
[InlineData(Avalonia.Layout.VerticalAlignment.Center)]
[InlineData(Avalonia.Layout.VerticalAlignment.Bottom)]
[InlineData(Avalonia.Layout.VerticalAlignment.Stretch)]
public void VerticalContentAlignment_RoundTrips ( Avalonia . Layout . VerticalAlignment value )
{
var timePicker = new TimePicker { VerticalContentAlignment = value } ;
Assert . Equal ( value , timePicker . VerticalContentAlignment ) ;
}
[Fact]
public void VerticalContentAlignment_Default_Is_Stretch ( )
{
var timePicker = new TimePicker ( ) ;
Assert . Equal ( Avalonia . Layout . VerticalAlignment . Stretch , timePicker . VerticalContentAlignment ) ;
}
}
}