Skip to content

Commit 9696fc0

Browse files
committed
code is working
1 parent 6a05a3c commit 9696fc0

File tree

2 files changed

+89
-16
lines changed

2 files changed

+89
-16
lines changed

Microsoft.Toolkit.Uwp.UI.Controls/WrapPanel/WrapPanel.Data.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using Windows.Foundation;
56
using Windows.UI.Xaml.Controls;
67

78
namespace Microsoft.Toolkit.Uwp.UI.Controls
@@ -14,12 +15,17 @@ public partial class WrapPanel
1415
[System.Diagnostics.DebuggerDisplay("U = {U} V = {V}")]
1516
private struct UvMeasure
1617
{
17-
internal static readonly UvMeasure Zero = default(UvMeasure);
18+
internal static readonly UvMeasure Zero = default;
1819

1920
internal double U { get; set; }
2021

2122
internal double V { get; set; }
2223

24+
public UvMeasure(Orientation orientation, Size size)
25+
: this(orientation, size.Width, size.Height)
26+
{
27+
}
28+
2329
public UvMeasure(Orientation orientation, double width, double height)
2430
{
2531
if (orientation == Orientation.Horizontal)

Microsoft.Toolkit.Uwp.UI.Controls/WrapPanel/WrapPanel.cs

Lines changed: 82 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
// See the LICENSE file in the project root for more information.
44

55
using System;
6+
using System.Collections.Generic;
7+
using System.Linq;
68
using Windows.Foundation;
79
using Windows.UI.Xaml;
810
using Windows.UI.Xaml.Controls;
@@ -54,6 +56,24 @@ public double VerticalSpacing
5456
typeof(WrapPanel),
5557
new PropertyMetadata(0d, LayoutPropertyChanged));
5658

59+
/// <summary>
60+
/// Gets or sets the vertical alignment to use when the control <see cref="Orientation"/> is set to <see cref="Orientation.Horizontal"/>.
61+
/// </summary>
62+
public VerticalAlignment VerticalContentAlignment
63+
{
64+
get => (VerticalAlignment)GetValue(VerticalContentAlignmentProperty);
65+
set => SetValue(VerticalContentAlignmentProperty, value);
66+
}
67+
68+
/// <summary>
69+
/// The DP to store the <see cref="VerticalContentAlignment"/> property value.
70+
/// </summary>
71+
public static readonly DependencyProperty VerticalContentAlignmentProperty = DependencyProperty.Register(
72+
nameof(VerticalContentAlignment),
73+
typeof(VerticalAlignment),
74+
typeof(WrapPanel),
75+
new PropertyMetadata(VerticalAlignment.Top));
76+
5777
/// <summary>
5878
/// Gets or sets the orientation of the WrapPanel.
5979
/// Horizontal means that child controls will be added horizontally until the width of the panel is reached, then a new row is added to add new child controls.
@@ -141,7 +161,7 @@ protected override Size MeasureOverride(Size availableSize)
141161
foreach (var child in Children)
142162
{
143163
child.Measure(availableSize);
144-
var currentMeasure = new UvMeasure(Orientation, child.DesiredSize.Width, child.DesiredSize.Height);
164+
var currentMeasure = new UvMeasure(Orientation, child.DesiredSize);
145165
if (currentMeasure.U == 0)
146166
{
147167
continue; // ignore collapsed items
@@ -207,10 +227,14 @@ protected override Size ArrangeOverride(Size finalSize)
207227
var paddingEnd = new UvMeasure(Orientation, Padding.Right, Padding.Bottom);
208228
var position = new UvMeasure(Orientation, Padding.Left, Padding.Top);
209229

210-
double currentV = 0;
211-
void Arrange(UIElement child, bool isLast = false)
230+
var allMeasures = Children.Select(c => new UvMeasure(Orientation, c.DesiredSize)).ToList();
231+
var allData = new List<(UvMeasure position, UvMeasure size)>();
232+
233+
var currentV = 0.0;
234+
void Arrange(int childIndex, bool isLast = false)
212235
{
213-
var desiredMeasure = new UvMeasure(Orientation, child.DesiredSize.Width, child.DesiredSize.Height);
236+
var child = Children[childIndex];
237+
var desiredMeasure = allMeasures[childIndex];
214238
if (desiredMeasure.U == 0)
215239
{
216240
return; // if an item is collapsed, avoid adding the spacing
@@ -230,15 +254,7 @@ void Arrange(UIElement child, bool isLast = false)
230254
desiredMeasure.U = parentMeasure.U - position.U;
231255
}
232256

233-
// place the item
234-
if (Orientation == Orientation.Horizontal)
235-
{
236-
child.Arrange(new Rect(position.U, position.V, desiredMeasure.U, desiredMeasure.V));
237-
}
238-
else
239-
{
240-
child.Arrange(new Rect(position.V, position.U, desiredMeasure.V, desiredMeasure.U));
241-
}
257+
allData.Add((position, desiredMeasure));
242258

243259
// adjust the location for the next items
244260
position.U += desiredMeasure.U + spacingMeasure.U;
@@ -248,10 +264,61 @@ void Arrange(UIElement child, bool isLast = false)
248264
var lastIndex = Children.Count - 1;
249265
for (var i = 0; i < lastIndex; i++)
250266
{
251-
Arrange(Children[i]);
267+
Arrange(i);
252268
}
253269

254-
Arrange(Children[lastIndex], StretchChild == StretchChild.Last);
270+
Arrange(lastIndex, StretchChild == StretchChild.Last);
271+
272+
// Now that we have all the data, we do the actual arrange pass
273+
var lastArrangeV = -1.0;
274+
var maxRowHeight = 0.0;
275+
for (var i = 0; i < Children.Count; i++)
276+
{
277+
// place the item
278+
var child = Children[i];
279+
(UvMeasure arrangePosition, UvMeasure arrangeMeasure) = allData[i];
280+
281+
if (lastArrangeV != arrangePosition.V)
282+
{
283+
// We are on a new row, we scan all the items to get the max row height
284+
maxRowHeight = allData
285+
.Skip(i) // ignore what has already being processed
286+
.TakeWhile(d => d.position.V == arrangePosition.V) // we are still on the same row
287+
.Max(d => d.size.V); // We want the max.
288+
}
289+
290+
if (Orientation == Orientation.Horizontal)
291+
{
292+
switch (VerticalContentAlignment)
293+
{
294+
case VerticalAlignment.Center:
295+
{
296+
var vOffset = Math.Max((maxRowHeight - arrangeMeasure.V) / 2.0, 0.0);
297+
child.Arrange(new Rect(arrangePosition.U, arrangePosition.V + vOffset, arrangeMeasure.U, arrangeMeasure.V));
298+
break;
299+
}
300+
301+
case VerticalAlignment.Bottom:
302+
{
303+
var vOffset = Math.Max(maxRowHeight - arrangeMeasure.V, 0.0);
304+
child.Arrange(new Rect(arrangePosition.U, arrangePosition.V + vOffset, arrangeMeasure.U, arrangeMeasure.V));
305+
break;
306+
}
307+
308+
case VerticalAlignment.Stretch:
309+
child.Arrange(new Rect(arrangePosition.U, arrangePosition.V, arrangeMeasure.U, maxRowHeight));
310+
break;
311+
case VerticalAlignment.Top:
312+
default:
313+
child.Arrange(new Rect(arrangePosition.U, arrangePosition.V, arrangeMeasure.U, arrangeMeasure.V));
314+
break;
315+
}
316+
}
317+
else
318+
{
319+
child.Arrange(new Rect(arrangePosition.V, arrangePosition.U, arrangeMeasure.V, arrangeMeasure.U));
320+
}
321+
}
255322
}
256323

257324
return finalSize;

0 commit comments

Comments
 (0)