Skip to content

Commit a146188

Browse files
Merge branch 'main' into fix-segmenteditem-visibility-issue
2 parents 4498345 + 8cea593 commit a146188

18 files changed

+339
-14
lines changed

.config/dotnet-tools.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"isRoot": true,
44
"tools": {
55
"uno.check": {
6-
"version": "1.27.4",
6+
"version": "1.33.1",
77
"commands": [
88
"uno-check"
99
]

.github/workflows/build.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ jobs:
121121
--skip wsl
122122
--skip androidemulator
123123
--skip vswinworkloads
124+
--skip vswin
124125
--verbose
125126
126127
- name: Add msbuild to PATH
@@ -254,6 +255,7 @@ jobs:
254255
--skip wsl
255256
--skip androidemulator
256257
--skip vswinworkloads
258+
--skip vswin
257259
--verbose
258260
259261
- name: Add msbuild to PATH

components/ColorPicker/src/ColorPicker.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ namespace CommunityToolkit.WinUI.Controls;
4646
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumControl), Type = typeof(ColorSpectrum))]
4747
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumAlphaSlider), Type = typeof(ColorPickerSlider))]
4848
[TemplatePart(Name = nameof(ColorPicker.ColorSpectrumThirdDimensionSlider), Type = typeof(ColorPickerSlider))]
49+
[TemplatePart(Name = nameof(ColorPicker.PaletteItemGridView), Type = typeof(GridView))]
4950
[TemplatePart(Name = nameof(ColorPicker.HexInputTextBox), Type = typeof(TextBox))]
5051
[TemplatePart(Name = nameof(ColorPicker.ColorModeComboBox), Type = typeof(ComboBox))]
5152

@@ -81,6 +82,7 @@ public partial class ColorPicker : Microsoft.UI.Xaml.Controls.ColorPicker
8182
private ColorSpectrum ColorSpectrumControl;
8283
private ColorPickerSlider ColorSpectrumAlphaSlider;
8384
private ColorPickerSlider ColorSpectrumThirdDimensionSlider;
85+
private GridView PaletteItemGridView;
8486
private TextBox HexInputTextBox;
8587
private ComboBox ColorModeComboBox;
8688

@@ -186,6 +188,8 @@ protected override void OnApplyTemplate()
186188
this.ColorSpectrumAlphaSlider = (ColorPickerSlider)this.GetTemplateChild(nameof(ColorSpectrumAlphaSlider));
187189
this.ColorSpectrumThirdDimensionSlider = (ColorPickerSlider)this.GetTemplateChild(nameof(ColorSpectrumThirdDimensionSlider));
188190

191+
this.PaletteItemGridView = (GridView)GetTemplateChild(nameof(PaletteItemGridView));
192+
189193
this.HexInputTextBox = (TextBox)this.GetTemplateChild(nameof(HexInputTextBox));
190194
this.ColorModeComboBox = (ComboBox)this.GetTemplateChild(nameof(ColorModeComboBox));
191195

@@ -263,6 +267,9 @@ private void ConnectEvents(bool connected)
263267

264268
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.ColorChanged += ColorSpectrum_ColorChanged; }
265269
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.GotFocus += ColorSpectrum_GotFocus; }
270+
271+
if (this.PaletteItemGridView != null) { this.PaletteItemGridView.SelectionChanged += this.PaletteItemGridView_SelectionChanged; }
272+
266273
if (this.HexInputTextBox != null) { this.HexInputTextBox.KeyDown += HexInputTextBox_KeyDown; }
267274
if (this.HexInputTextBox != null) { this.HexInputTextBox.LostFocus += HexInputTextBox_LostFocus; }
268275
if (this.ColorModeComboBox != null) { this.ColorModeComboBox.SelectionChanged += ColorModeComboBox_SelectionChanged; }
@@ -309,6 +316,9 @@ private void ConnectEvents(bool connected)
309316

310317
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.ColorChanged -= ColorSpectrum_ColorChanged; }
311318
if (this.ColorSpectrumControl != null) { this.ColorSpectrumControl.GotFocus -= ColorSpectrum_GotFocus; }
319+
320+
if (this.PaletteItemGridView != null) { this.PaletteItemGridView.SelectionChanged -= this.PaletteItemGridView_SelectionChanged; }
321+
312322
if (this.HexInputTextBox != null) { this.HexInputTextBox.KeyDown -= HexInputTextBox_KeyDown; }
313323
if (this.HexInputTextBox != null) { this.HexInputTextBox.LostFocus -= HexInputTextBox_LostFocus; }
314324
if (this.ColorModeComboBox != null) { this.ColorModeComboBox.SelectionChanged -= ColorModeComboBox_SelectionChanged; }
@@ -1325,6 +1335,20 @@ private void ColorSpectrum_GotFocus(object sender, RoutedEventArgs e)
13251335
return;
13261336
}
13271337

1338+
/// <summary>
1339+
/// Event handler for when a color is selected from the palette.
1340+
/// This will update the current color.
1341+
/// </summary>
1342+
private void PaletteItemGridView_SelectionChanged(object sender, SelectionChangedEventArgs e)
1343+
{
1344+
if ((sender as GridView)?.SelectedValue is not Color selectedColor)
1345+
{
1346+
return;
1347+
}
1348+
1349+
this.Color = selectedColor;
1350+
}
1351+
13281352
/// <summary>
13291353
/// Event handler for when the selected color representation changes.
13301354
/// This will convert between RGB and HSV.

components/ColorPicker/src/ColorPicker.xaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -286,12 +286,12 @@
286286
</controls:Case>
287287
<controls:Case Value="PaletteItem">
288288
<Grid HorizontalAlignment="Stretch">
289-
<GridView Margin="0"
289+
<GridView x:Name="PaletteItemGridView"
290+
Margin="0"
290291
Padding="0"
291292
animations:Implicit.HideAnimations="{StaticResource HideTransitions}"
292293
animations:Implicit.ShowAnimations="{StaticResource ShowTransitions}"
293294
ItemsSource="{TemplateBinding CustomPaletteColors}"
294-
SelectedValue="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Color, Converter={StaticResource NullToTransparentConverter}, Mode=TwoWay}"
295295
SelectionMode="Single"
296296
Tag="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Color, Mode=OneWay}">
297297
<GridView.ItemsPanel>

components/Primitives/samples/WrapPanel.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Spacing can be automatically added between items using the HorizontalSpacing and
2020

2121
When the Orientation is Vertical, HorizontalSpacing adds uniform spacing between each column of items, and VerticalSpacing adds uniform vertical spacing between individual items.
2222

23+
> [!NOTE]
24+
> When `StretchChild="Last"` is set, the last child will only stretch if the available measure size is finite. If the panel is measured with an infinite width (for horizontal orientation) or infinite height (for vertical orientation), the last child will not stretch.
25+
2326
> [!SAMPLE WrapPanelSample]
2427
2528
## Examples

components/Primitives/src/WrapPanel/WrapPanel.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,12 @@ public Thickness Padding
9797
/// <summary>
9898
/// Gets or sets a value indicating how to arrange child items
9999
/// </summary>
100+
/// <remarks>
101+
/// When the available size provided to the panel is infinite (for example,
102+
/// when placed in a container with Auto sizing), the last child will not be
103+
/// stretched. Attempting to stretch in this scenario would cause the element
104+
/// to expand to an infinite size and result in a runtime exception.
105+
/// </remarks>
100106
public StretchChild StretchChild
101107
{
102108
get { return (StretchChild)GetValue(StretchChildProperty); }
@@ -219,7 +225,8 @@ void Arrange(UIElement child, bool isLast = false)
219225
}
220226

221227
// Stretch the last item to fill the available space
222-
if (isLast)
228+
// if the parent measure is not infinite
229+
if (isLast && !double.IsInfinity(parentMeasure.U))
223230
{
224231
desiredMeasure.U = parentMeasure.U - position.U;
225232
}

components/Primitives/tests/Primitives.Tests.projitems

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,23 @@
3333
<Compile Include="$(MSBuildThisFileDirectory)Test_UniformGrid_FreeSpots.cs" />
3434
<Compile Include="$(MSBuildThisFileDirectory)Test_UniformGrid_RowColDefinitions.cs" />
3535
<Compile Include="$(MSBuildThisFileDirectory)Test_WrapPanel_BasicLayout.cs" />
36+
<Compile Include="$(MSBuildThisFileDirectory)Test_WrapPanel_StretchChild.cs" />
3637
<Compile Include="$(MSBuildThisFileDirectory)Test_WrapPanel_Visibility.cs" />
3738
<Compile Include="$(MSBuildThisFileDirectory)UniformGrid\AutoLayoutFixedElementZeroZeroSpecialPage.xaml.cs">
3839
<DependentUpon>AutoLayoutFixedElementZeroZeroSpecialPage.xaml</DependentUpon>
3940
</Compile>
41+
<Compile Include="$(MSBuildThisFileDirectory)WrapPanel\HorizontalWrapPanelInsideParentWithInfinityWidth.xaml.cs">
42+
<DependentUpon>HorizontalWrapPanelInsideParentWithInfinityWidth.xaml</DependentUpon>
43+
</Compile>
44+
<Compile Include="$(MSBuildThisFileDirectory)WrapPanel\HorizontalWrapPanelInsideParentWithLimitedWidth.xaml.cs">
45+
<DependentUpon>HorizontalWrapPanelInsideParentWithLimitedWidth.xaml</DependentUpon>
46+
</Compile>
47+
<Compile Include="$(MSBuildThisFileDirectory)WrapPanel\VerticalWrapPanelInsideParentWithInfinityHeight.xaml.cs">
48+
<DependentUpon>VerticalWrapPanelInsideParentWithInfinityHeight.xaml</DependentUpon>
49+
</Compile>
50+
<Compile Include="$(MSBuildThisFileDirectory)WrapPanel\VerticalWrapPanelInsideParentWithLimitedHeight.xaml.cs">
51+
<DependentUpon>VerticalWrapPanelInsideParentWithLimitedHeight.xaml</DependentUpon>
52+
</Compile>
4053
</ItemGroup>
4154
<ItemGroup>
4255
<Page Include="$(MSBuildThisFileDirectory)DockPanel\DockPanelSample.xaml">
@@ -47,6 +60,22 @@
4760
<SubType>Designer</SubType>
4861
<Generator>MSBuild:Compile</Generator>
4962
</Page>
63+
<Page Include="$(MSBuildThisFileDirectory)WrapPanel\HorizontalWrapPanelInsideParentWithInfinityWidth.xaml">
64+
<SubType>Designer</SubType>
65+
<Generator>MSBuild:Compile</Generator>
66+
</Page>
67+
<Page Include="$(MSBuildThisFileDirectory)WrapPanel\HorizontalWrapPanelInsideParentWithLimitedWidth.xaml">
68+
<SubType>Designer</SubType>
69+
<Generator>MSBuild:Compile</Generator>
70+
</Page>
71+
<Page Include="$(MSBuildThisFileDirectory)WrapPanel\VerticalWrapPanelInsideParentWithInfinityHeight.xaml">
72+
<SubType>Designer</SubType>
73+
<Generator>MSBuild:Compile</Generator>
74+
</Page>
75+
<Page Include="$(MSBuildThisFileDirectory)WrapPanel\VerticalWrapPanelInsideParentWithLimitedHeight.xaml">
76+
<SubType>Designer</SubType>
77+
<Generator>MSBuild:Compile</Generator>
78+
</Page>
5079
</ItemGroup>
5180
<ItemGroup>
5281
<Page Include="$(MSBuildThisFileDirectory)SwitchPresenter\SwitchConverterBrushSample.xaml">
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
using CommunityToolkit.Tests;
6+
using CommunityToolkit.Tooling.TestGen;
7+
using CommunityToolkit.WinUI.Controls;
8+
9+
namespace PrimitivesTests;
10+
11+
[TestClass]
12+
public partial class Test_WrapPanel_StretchChild : VisualUITestBase
13+
{
14+
/// <summary>
15+
/// When a WrapPanel is inside a parent with infinite width, the last child cannot stretch to fill the remaining space.
16+
/// Instead, it should measure to its desired size.
17+
/// </summary>
18+
[TestCategory("WrapPanel")]
19+
[UIThreadTestMethod]
20+
public void VerticalWrapPanelInsideParentWithInfinityHeightTest(VerticalWrapPanelInsideParentWithInfinityHeight page)
21+
{
22+
var wrapPanel = page.FindDescendant<WrapPanel>();
23+
Assert.IsNotNull(wrapPanel, "Could not find WrapPanel.");
24+
Assert.IsFalse(wrapPanel.StretchChild is not StretchChild.Last, "WrapPanel StretchChild property not set to Last.");
25+
Assert.IsFalse(wrapPanel.Children.Count < 1, "No children to test.");
26+
27+
foreach (var child in wrapPanel.Children.Cast<FrameworkElement>())
28+
{
29+
double expectedHeight = child.DesiredSize.Height;
30+
Assert.AreEqual(expectedHeight, child.ActualHeight, "Child height not as expected.");
31+
}
32+
}
33+
34+
/// <summary>
35+
/// When a WrapPanel is inside a parent with limited height, the last child with Stretch alignment should fill the remaining space.
36+
/// </summary>
37+
[TestCategory("WrapPanel")]
38+
[UIThreadTestMethod]
39+
public void VerticalWrapPanelInsideParentWithLimitedHeightTest(VerticalWrapPanelInsideParentWithLimitedHeight page)
40+
{
41+
var wrapPanel = page.FindDescendant<WrapPanel>();
42+
Assert.IsNotNull(wrapPanel, "Could not find WrapPanel.");
43+
Assert.IsFalse(wrapPanel.StretchChild is not StretchChild.Last, "WrapPanel StretchChild property not set to Last.");
44+
Assert.IsFalse(wrapPanel.Children.Count < 1, "No children to test.");
45+
46+
var precedingChildren = wrapPanel.Children.Cast<FrameworkElement>().Take(wrapPanel.Children.Count - 1);
47+
48+
foreach (var child in precedingChildren)
49+
{
50+
double expectedHeight = child.DesiredSize.Height;
51+
Assert.AreEqual(expectedHeight, child.ActualHeight, "Preceding child height not as expected.");
52+
}
53+
54+
var lastChild = wrapPanel.Children.Cast<FrameworkElement>().Last();
55+
double lastChildExpectedHeight = wrapPanel.ActualHeight - precedingChildren.Sum(child => child.ActualHeight);
56+
Assert.AreEqual(lastChildExpectedHeight, lastChild.ActualHeight, "Last child height not as expected.");
57+
}
58+
59+
/// <summary>
60+
/// When a WrapPanel is inside a parent with infinite width, the last child cannot stretch to fill the remaining space.
61+
/// Instead, it should measure to its desired size.
62+
/// </summary>
63+
[TestCategory("WrapPanel")]
64+
[UIThreadTestMethod]
65+
public void HorizontalWrapPanelInsideParentWithInfinityWidthTest(HorizontalWrapPanelInsideParentWithInfinityWidth page)
66+
{
67+
var wrapPanel = page.FindDescendant<WrapPanel>();
68+
Assert.IsNotNull(wrapPanel, "Could not find WrapPanel.");
69+
Assert.IsFalse(wrapPanel.StretchChild is not StretchChild.Last, "WrapPanel StretchChild property not set to Last.");
70+
Assert.IsFalse(wrapPanel.Children.Count < 1, "No children to test.");
71+
72+
foreach (var child in wrapPanel.Children.Cast<FrameworkElement>())
73+
{
74+
double expectedWidth = child.DesiredSize.Width;
75+
Assert.AreEqual(expectedWidth, child.ActualWidth, "Preceding child width not as expected.");
76+
}
77+
}
78+
79+
/// <summary>
80+
/// When a WrapPanel is inside a parent with limited width, the last child with Stretch alignment should fill the remaining space.
81+
/// </summary>
82+
/// <param name="page"></param>
83+
[TestCategory("WrapPanel")]
84+
[UIThreadTestMethod]
85+
public void HorizontalWrapPanelInsideParentWithLimitedWidthTest(HorizontalWrapPanelInsideParentWithLimitedWidth page)
86+
{
87+
var wrapPanel = page.FindDescendant<WrapPanel>();
88+
Assert.IsNotNull(wrapPanel, "Could not find WrapPanel.");
89+
Assert.IsFalse(wrapPanel.StretchChild is not StretchChild.Last, "WrapPanel StretchChild property not set to Last.");
90+
Assert.IsFalse(wrapPanel.Children.Count < 1, "No children to test.");
91+
92+
var precedingChildren = wrapPanel.Children.Cast<FrameworkElement>().Take(wrapPanel.Children.Count - 1);
93+
94+
foreach (var child in precedingChildren)
95+
{
96+
double expectedWidth = child.DesiredSize.Width;
97+
Assert.AreEqual(expectedWidth, child.ActualWidth, "Child width not as expected.");
98+
}
99+
100+
var lastChild = wrapPanel.Children.Cast<FrameworkElement>().Last();
101+
double lastChildExpectedWidth = wrapPanel.ActualWidth - precedingChildren.Sum(child => child.ActualWidth);
102+
Assert.AreEqual(lastChildExpectedWidth, lastChild.ActualWidth, "Last child width not as expected.");
103+
}
104+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Page x:Class="PrimitivesTests.HorizontalWrapPanelInsideParentWithInfinityWidth"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:controls="using:CommunityToolkit.WinUI.Controls"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:local="using:PrimitivesTests"
7+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
8+
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
9+
mc:Ignorable="d">
10+
11+
<Grid>
12+
<Grid.ColumnDefinitions>
13+
<ColumnDefinition Width="Auto" />
14+
</Grid.ColumnDefinitions>
15+
<controls:WrapPanel Orientation="Horizontal"
16+
StretchChild="Last">
17+
<Button HorizontalAlignment="Stretch"
18+
Content="Child 1" />
19+
<Button HorizontalAlignment="Stretch"
20+
Content="Child 2" />
21+
<Button HorizontalAlignment="Stretch"
22+
Content="Last Child" />
23+
</controls:WrapPanel>
24+
</Grid>
25+
26+
</Page>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
// See the LICENSE file in the project root for more information.
4+
5+
namespace PrimitivesTests;
6+
7+
public sealed partial class HorizontalWrapPanelInsideParentWithInfinityWidth : Page
8+
{
9+
public HorizontalWrapPanelInsideParentWithInfinityWidth()
10+
{
11+
this.InitializeComponent();
12+
}
13+
}

0 commit comments

Comments
 (0)