Skip to content

Commit 857695f

Browse files
Add Value Coercion and Tests for ConstrainedBox
1 parent 2c7e8c2 commit 857695f

File tree

3 files changed

+199
-1
lines changed

3 files changed

+199
-1
lines changed

Microsoft.Toolkit.Uwp.UI.Controls.Primitives/ConstrainedBox/ConstrainedBox.Properties.cs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,71 @@ public AspectRatio AspectRatio
9393
public static readonly DependencyProperty AspectRatioProperty =
9494
DependencyProperty.Register(nameof(AspectRatio), typeof(AspectRatio), typeof(ConstrainedBox), new PropertyMetadata(null, ConstraintPropertyChanged));
9595

96+
private bool _propertyUpdating;
97+
9698
private static void ConstraintPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
9799
{
98-
if (d is ConstrainedBox panel)
100+
if (d is ConstrainedBox panel && !panel._propertyUpdating)
99101
{
102+
panel._propertyUpdating = true;
103+
104+
panel.CoerceValues();
105+
100106
panel.InvalidateMeasure();
107+
108+
panel._propertyUpdating = false;
109+
}
110+
}
111+
112+
private void CoerceValues()
113+
{
114+
// Check if scale properties are in range
115+
if (!double.IsNaN(ScaleX))
116+
{
117+
if (ScaleX < 0)
118+
{
119+
ScaleX = 0;
120+
}
121+
else if (ScaleX > 1.0)
122+
{
123+
ScaleX = 1.0;
124+
}
125+
}
126+
else
127+
{
128+
ScaleX = 1.0;
129+
}
130+
131+
if (!double.IsNaN(ScaleY))
132+
{
133+
if (ScaleY < 0)
134+
{
135+
ScaleY = 0;
136+
}
137+
else if (ScaleY > 1.0)
138+
{
139+
ScaleY = 1.0;
140+
}
141+
}
142+
else
143+
{
144+
ScaleY = 1.0;
145+
}
146+
147+
// Clear invalid values less than 0 for other properties
148+
if (ReadLocalValue(MultipleXProperty) is int value && value <= 0)
149+
{
150+
ClearValue(MultipleXProperty);
151+
}
152+
153+
if (ReadLocalValue(MultipleYProperty) is int value2 && value2 <= 0)
154+
{
155+
ClearValue(MultipleYProperty);
156+
}
157+
158+
if (ReadLocalValue(AspectRatioProperty) is AspectRatio ratio && ratio <= 0)
159+
{
160+
ClearValue(AspectRatioProperty);
101161
}
102162
}
103163
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
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 System.Linq;
6+
using System.Threading.Tasks;
7+
using Microsoft.Toolkit.Uwp;
8+
using Microsoft.Toolkit.Uwp.UI;
9+
using Microsoft.Toolkit.Uwp.UI.Controls;
10+
using Microsoft.VisualStudio.TestTools.UnitTesting;
11+
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
12+
using Windows.Foundation;
13+
using Windows.UI.Xaml;
14+
using Windows.UI.Xaml.Controls;
15+
using Windows.UI.Xaml.Markup;
16+
17+
namespace UnitTests.UWP.UI.Controls
18+
{
19+
public partial class Test_ConstrainedBox : VisualUITestBase
20+
{
21+
[TestCategory("ConstrainedBox")]
22+
[TestMethod]
23+
public async Task Test_ConstrainedBox_Coerce_Scale()
24+
{
25+
await App.DispatcherQueue.EnqueueAsync(async () =>
26+
{
27+
var treeRoot = XamlReader.Load(@"<Page
28+
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
29+
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
30+
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
31+
<controls:ConstrainedBox x:Name=""ConstrainedBox"" ScaleX=""0.5"" ScaleY=""0.5""/>
32+
</Page>") as FrameworkElement;
33+
34+
Assert.IsNotNull(treeRoot, "Could not load XAML tree.");
35+
36+
// Initialize Visual Tree
37+
await SetTestContentAsync(treeRoot);
38+
39+
var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;
40+
41+
Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");
42+
43+
// Check Size
44+
Assert.AreEqual(0.5, panel.ScaleX, 0.01, "ScaleX does not meet expected initial value of 0.5");
45+
Assert.AreEqual(0.5, panel.ScaleY, 0.01, "ScaleY does not meet expected initial value of 0.5");
46+
47+
// Change values now to be invalid
48+
panel.ScaleX = double.NaN;
49+
panel.ScaleY = double.NaN;
50+
51+
Assert.AreEqual(1.0, panel.ScaleX, 0.01, "ScaleX does not meet expected value of 1.0 after change.");
52+
Assert.AreEqual(1.0, panel.ScaleY, 0.01, "ScaleY does not meet expected value of 1.0 after change.");
53+
54+
// Change values now to be invalid
55+
panel.ScaleX = double.NegativeInfinity;
56+
panel.ScaleY = double.NegativeInfinity;
57+
58+
Assert.AreEqual(0.0, panel.ScaleX, 0.01, "ScaleX does not meet expected value of 0.0 after change.");
59+
Assert.AreEqual(0.0, panel.ScaleY, 0.01, "ScaleY does not meet expected value of 0.0 after change.");
60+
61+
// Change values now to be invalid
62+
panel.ScaleX = double.PositiveInfinity;
63+
panel.ScaleY = double.PositiveInfinity;
64+
65+
Assert.AreEqual(1.0, panel.ScaleX, 0.01, "ScaleX does not meet expected value of 1.0 after change.");
66+
Assert.AreEqual(1.0, panel.ScaleY, 0.01, "ScaleY does not meet expected value of 1.0 after change.");
67+
});
68+
}
69+
70+
[TestCategory("ConstrainedBox")]
71+
[TestMethod]
72+
public async Task Test_ConstrainedBox_Coerce_Multiple()
73+
{
74+
await App.DispatcherQueue.EnqueueAsync(async () =>
75+
{
76+
var treeRoot = XamlReader.Load(@"<Page
77+
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
78+
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
79+
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
80+
<controls:ConstrainedBox x:Name=""ConstrainedBox"" MultipleX=""32"" MultipleY=""32""/>
81+
</Page>") as FrameworkElement;
82+
83+
Assert.IsNotNull(treeRoot, "Could not load XAML tree.");
84+
85+
// Initialize Visual Tree
86+
await SetTestContentAsync(treeRoot);
87+
88+
var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;
89+
90+
Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");
91+
92+
// Check Size
93+
Assert.AreEqual(32, panel.MultipleX, "MultipleX does not meet expected value of 32");
94+
Assert.AreEqual(32, panel.MultipleY, "MultipleY does not meet expected value of 32");
95+
96+
// Change values now to be invalid
97+
panel.MultipleX = 0;
98+
panel.MultipleY = int.MinValue;
99+
100+
Assert.AreEqual(DependencyProperty.UnsetValue, panel.ReadLocalValue(ConstrainedBox.MultipleXProperty), "MultipleX does not meet expected value of UnsetValue after change.");
101+
Assert.AreEqual(DependencyProperty.UnsetValue, panel.ReadLocalValue(ConstrainedBox.MultipleYProperty), "MultipleY does not meet expected value of UnsetValue after change.");
102+
});
103+
}
104+
105+
[TestCategory("ConstrainedBox")]
106+
[TestMethod]
107+
public async Task Test_ConstrainedBox_Coerce_AspectRatio()
108+
{
109+
await App.DispatcherQueue.EnqueueAsync(async () =>
110+
{
111+
var treeRoot = XamlReader.Load(@"<Page
112+
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
113+
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
114+
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
115+
<controls:ConstrainedBox x:Name=""ConstrainedBox"" AspectRatio=""1.25:3.5""/>
116+
</Page>") as FrameworkElement;
117+
118+
Assert.IsNotNull(treeRoot, "Could not load XAML tree.");
119+
120+
// Initialize Visual Tree
121+
await SetTestContentAsync(treeRoot);
122+
123+
var panel = treeRoot.FindChild("ConstrainedBox") as ConstrainedBox;
124+
125+
Assert.IsNotNull(panel, "Could not find ConstrainedBox in tree.");
126+
127+
// Check Size
128+
Assert.AreEqual(1.25 / 3.5, panel.AspectRatio, 0.01, "ApectRatio does not meet expected value of 1.25/3.5");
129+
130+
// Change values now to be invalid
131+
panel.AspectRatio = -1;
132+
133+
Assert.AreEqual(DependencyProperty.UnsetValue, panel.ReadLocalValue(ConstrainedBox.AspectRatioProperty), "AspectRatio does not meet expected value of UnsetValue after change.");
134+
});
135+
}
136+
}
137+
}

UnitTests/UnitTests.UWP/UnitTests.UWP.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@
230230
<Compile Include="UI\Controls\Test_Carousel.cs" />
231231
<Compile Include="UI\Controls\Test_BladeView.cs" />
232232
<Compile Include="UI\Controls\Test_ConstrainedBox.AspectRatio.cs" />
233+
<Compile Include="UI\Controls\Test_ConstrainedBox.Coerce.cs" />
233234
<Compile Include="UI\Controls\Test_ConstrainedBox.Multiple.cs" />
234235
<Compile Include="UI\Controls\Test_ConstrainedBox.Combined.cs" />
235236
<Compile Include="UI\Controls\Test_ImageEx.cs" />

0 commit comments

Comments
 (0)