feat: add tests.

This commit is contained in:
Dong Bin
2025-09-03 15:26:38 +08:00
parent 37aa84edfb
commit bce6e08561
2 changed files with 218 additions and 4 deletions

View File

@@ -30,15 +30,21 @@ public class WrapPanelWithTrailingItem: Panel
base.OnPropertyChanged(change);
if (change.Property == TrailingItemProperty)
{
if(change.GetOldValue<Visual?>() is { } oldValue)
if(change.GetOldValue<Layoutable?>() is { } oldValue)
{
VisualChildren.Remove(oldValue);
LogicalChildren.Remove(oldValue);
if (!IsItemsHost)
{
LogicalChildren.Remove(oldValue);
}
}
if(change.GetNewValue<Visual?>() is {} newValue)
if(change.GetNewValue<Layoutable?>() is {} newValue)
{
VisualChildren.Add(newValue);
LogicalChildren.Add(newValue);
if (!IsItemsHost)
{
LogicalChildren.Add(newValue);
}
}
}
@@ -80,6 +86,7 @@ public class WrapPanelWithTrailingItem: Panel
}
var last = TrailingItem;
if (last is null) return new Size(availableSize.Width, totalHeight);
last.Measure(availableSize);
double lastDeltaX = availableSize.Width - currentLineX;
// If width is not enough, add a new line, and recalculate total height
@@ -96,4 +103,56 @@ public class WrapPanelWithTrailingItem: Panel
return new Size(availableSize.Width, totalHeight);
}
protected override Size ArrangeOverride(Size finalSize)
{
double currentLineX = 0;
double currentLineHeight = 0;
double totalHeight = 0;
var children = Children;
for (int i = 0; i < children.Count; i++)
{
var child = children[i];
double deltaX = finalSize.Width - currentLineX;
// Width is enough to place next child
if (MathHelpers.GreaterThan(deltaX, child.DesiredSize.Width))
{
child.Arrange(new Rect(currentLineX, totalHeight, child.DesiredSize.Width, Math.Max(child.DesiredSize.Height, currentLineHeight)));
currentLineX += child.DesiredSize.Width;
currentLineHeight = Math.Max(currentLineHeight, child.DesiredSize.Height);
}
// Width is not enough to place next child
// reset currentLineX and currentLineHeight
// accumulate last line height to total height.
// Notice: last line height accumulation only happens when restarting a new line, so it needs to finally add one more time outside iteration.
else
{
totalHeight += currentLineHeight;
child.Arrange(new Rect(0, totalHeight, Math.Min(child.DesiredSize.Width, finalSize.Width), child.DesiredSize.Height));
currentLineX = child.DesiredSize.Width;
currentLineHeight = child.DesiredSize.Height;
}
}
var last = TrailingItem;
if (last is null) return new Size(finalSize.Width, totalHeight);
double lastDeltaX = finalSize.Width - currentLineX;
// If width is not enough, add a new line, and recalculate total height
if (lastDeltaX < 30)
{
totalHeight += currentLineHeight;
last.Arrange(new Rect(0, totalHeight, finalSize.Width, last.DesiredSize.Height));
totalHeight += last.DesiredSize.Height;
}
else
{
currentLineHeight = children.Count == 1 ? finalSize.Height : currentLineHeight;
last.Arrange(new Rect(currentLineX, totalHeight, lastDeltaX,
Math.Max(currentLineHeight, last.DesiredSize.Height)));
currentLineHeight = Math.Max(currentLineHeight, last.DesiredSize.Height);
totalHeight += currentLineHeight;
}
return new Size(finalSize.Width, totalHeight);
}
}