我有一个 XAML 布局,在 StackPanel 中包含一系列按钮:
<StackPanel Orientation="Horizontal" MaxWidth="200">
<Button Content="1"/>
<Button Content="2"/>
<Button Content="3"/>
<Button Content="4"/>
<Button Content="5"/>
<Button Content="6"/>
<Button Content="7"/>
</StackPanel>
我的目标是让这些按钮在单行中对齐,只要总宽度不超过 200。如果所有按钮的宽度超过 200,我希望它们自动重新排列成两行,每行都有一个偶数如果可能的话,分配按钮。 我尝试过使用
UniformGrid
和 WrapPanel
来满足此布局要求,但它们没有达到预期的效果。可能是我没有正确使用它们。
正如@Yoji 所建议的,包装板应该可以完成这项工作。 已使用以下代码测试并存档您所描述的内容:
<WrapPanel MaxWidth="200">
<Button Width="50" Content="1"/>
<Button Width="50" Content="2"/>
<Button Width="50" Content="3"/>
<Button Width="50" Content="4"/>
<Button Width="50" Content="5"/>
<Button Width="50" Content="6"/>
<Button Width="50" Content="7"/>
<Button Width="50" Content="7"/>
</WrapPanel>
更新: 根据您在评论中的描述,我给您写了一个符合我理解的小控件,应该可以解决问题
public class WrapperPanelExtended : WrapPanel
{
protected override Size ArrangeOverride(Size finalSize)
{
var itemsCount = InternalChildren.Count;
var MaxItemsPerColumn = (int)(finalSize.Width / InternalChildren[0].DesiredSize.Width);
var columntCount = (itemsCount / MaxItemsPerColumn) + 1;
MaxItemsPerColumn = itemsCount / columntCount;
for (var i = 0; i < InternalChildren.Count; i++)
{
var location = new Point(i % MaxItemsPerColumn * InternalChildren[i].DesiredSize.Width, i / MaxItemsPerColumn * InternalChildren[i].DesiredSize.Height);
InternalChildren[i].Arrange(new Rect(location, new Size(finalSize.Width, InternalChildren[i].DesiredSize.Height)));
}
return finalSize;
}
protected override Size MeasureOverride(Size constraint)
{
var _ = InternalChildren.Count;
return base.MeasureOverride(constraint);
}
}
在你的xaml中
<Local:WrapperPanelExtended MaxWidth="200">
<Button Width="50" Content="1"/>
<Button Width="50" Content="2"/>
<Button Width="50" Content="3"/>
<Button Width="50" Content="4"/>
<Button Width="50" Content="5"/>
<Button Width="50" Content="6"/>
<Button Width="50" Content="7"/>
<Button Width="50" Content="8"/>
<Button Width="50" Content="9"/>
<Button Width="50" Content="10"/>
</Local:WrapperPanelExtended>