我正在开发wpf窗口,它显示了包装下面的项目列表,我试图以这种方式使用WrapPanel
:
<Grid>
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Items>
<Button Content="01" Height="30" Width="70"/>
<Button Content="02" Height="35" Width="72"/>
<Button Content="03" Height="20" Width="74"/>
<Button Content="04" Height="25" Width="76"/>
<Button Content="05" Height="18" Width="78"/>
<Button Content="06" Height="50" Width="70"/>
<Button Content="07" Height="40" Width="72"/>
<Button Content="08" Height="55" Width="74"/>
<Button Content="09" Height="45" Width="76"/>
<Button Content="10" Height="25" Width="78"/>
<Button Content="11" Height="20" Width="80"/>
<Button Content="12" Height="30" Width="70"/>
<Button Content="13" Height="45" Width="72"/>
<Button Content="14" Height="30" Width="74"/>
<Button Content="15" Height="20" Width="76"/>
<Button Content="16" Height="25" Width="78"/>
<Button Content="17" Height="35" Width="80"/>
<Button Content="18" Height="50" Width="70"/>
<Button Content="19" Height="55" Width="72"/>
<Button Content="20" Height="45" Width="74"/>
<Button Content="21" Height="20" Width="76"/>
<Button Content="22" Height="60" Width="78"/>
<Button Content="23" Height="20" Width="80"/>
<Button Content="24" Height="25" Width="70"/>
<Button Content="25" Height="30" Width="72"/>
</ItemsControl.Items>
</ItemsControl>
</Grid>
这就是结果:
实际上这个结果对我来说并不令人满意,因为如果你想象WrapPanel
为网格(行和列),你会发现没有列,但是有固定大小的行。我需要制作WarpPanel
或其他没有列的控件,看看这个虚构的图像:
注意没有行,也没有列。这就是我想做的事。
有人有想法解决这个问题吗?
答案 0 :(得分:9)
您可以编写自己的自定义Panel类。网上有一些教程,只需谷歌“wpf自定义面板”。
归结为覆盖MeasureOverride和ArrangeOverride方法。
public class CustomPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
Size panelDesiredSize = new Size();
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
// Use child.DesiredSize, availableSize.Width and the positions
// and sizes of the previous children to calculate the position of
// the current child. Then determine the resulting Panel height.
panelDesiredSize = ...
}
return panelDesiredSize;
}
protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement child in InternalChildren)
{
// Arrange each child according to the position calculations
// done in MeasureOverride
Point position = ...
child.Arrange(new Rect(position, child.DesiredSize));
}
return finalSize;
}
}
更新:以下简单的自定义面板可能会或多或少地执行您想要的操作。
public class PackPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
}
var positions = new Point[InternalChildren.Count];
var desiredHeight = ArrangeChildren(positions, availableSize.Width);
return new Size(availableSize.Width, desiredHeight);
}
protected override Size ArrangeOverride(Size finalSize)
{
var positions = new Point[InternalChildren.Count];
ArrangeChildren(positions, finalSize.Width);
for (int i = 0; i < InternalChildren.Count; i++)
{
var child = InternalChildren[i];
child.Arrange(new Rect(positions[i], child.DesiredSize));
}
return finalSize;
}
private double ArrangeChildren(Point[] positions, double availableWidth)
{
var lastRowStartIndex = -1;
var lastRowEndIndex = 0;
var currentWidth = 0d;
var desiredHeight = 0d;
for (int childIndex = 0; childIndex < InternalChildren.Count; childIndex++)
{
var child = InternalChildren[childIndex];
var x = 0d;
var y = 0d;
if (currentWidth == 0d || currentWidth + child.DesiredSize.Width <= availableWidth)
{
x = currentWidth;
currentWidth += child.DesiredSize.Width;
}
else
{
currentWidth = child.DesiredSize.Width;
lastRowStartIndex = lastRowEndIndex;
lastRowEndIndex = childIndex;
}
if (lastRowStartIndex >= 0)
{
int i = lastRowStartIndex;
while (i < lastRowEndIndex - 1 && positions[i + 1].X < x)
{
i++;
}
while (i < lastRowEndIndex && positions[i].X < x + child.DesiredSize.Width)
{
y = Math.Max(y, positions[i].Y + InternalChildren[i].DesiredSize.Height);
i++;
}
}
positions[childIndex] = new Point(x, y);
desiredHeight = Math.Max(desiredHeight, y + child.DesiredSize.Height);
}
return desiredHeight;
}
}
答案 1 :(得分:-1)
你可以使用Canvas:
或使用网格并根据要求设置每个按钮的边距
<Canvas >
<Button Content="s" Width="50" Canvas.Left="17" Canvas.Top="20" />
<Button Canvas.Left="73" Canvas.Top="32" Content="s" Width="60" Height="42" />
<Button Canvas.Left="139" Canvas.Top="10" Content="s" Height="42" Width="60" />
</Canvas>
<Grid >
<Button Content="01" Height="30" Width="70" Margin="20,12,414,268" />
<Button Content="02" Height="35" Width="72" Margin="426,148,6,128" />
<Button Content="03" Height="20" Width="74" Margin="190,122,240,170" />
<Button Content="04" Height="25" Width="76" Margin="386,26,40,260" />
<Button Content="05" Height="18" Width="78" Margin="376,202,48,92" />
<Button Content="06" Height="50" Width="70" Margin="385,64,48,196" />
<Button Content="07" Height="40" Width="72" Margin="162,202,269,68" />
<Button Content="08" Height="55" Width="74" Margin="20,154,408,102" />
<Button Content="09" Height="45" Width="76" Margin="21,95,406,171" />
<Button Content="10" Height="25" Width="78" Margin="44,47,382,239" />
<Button Content="11" Height="20" Width="80" Margin="386,120,38,170" />
<Button Content="12" Height="30" Width="70" Margin="95,13,338,268" />
<Button Content="13" Height="45" Width="72" Margin="290,6,140,260" />
<Button Content="14" Height="30" Width="74" Margin="210,38,220,244" />
<Button Content="15" Height="20" Width="76" Margin="128,48,299,242" />
<Button Content="16" Height="25" Width="78" Margin="265,189,160,97" />
<Button Content="17" Height="35" Width="80" Margin="176,154,246,122" />
<Button Content="18" Height="50" Width="70" Margin="100,146,333,116" />
<Button Content="19" Height="55" Width="72" Margin="270,121,160,135" />
<Button Content="20" Height="45" Width="74" Margin="348,148,81,118" />
<Button Content="21" Height="20" Width="76" Margin="94,78,332,212" />
<Button Content="22" Height="60" Width="78" Margin="270,60,155,192" />
<Button Content="23" Height="20" Width="80" Margin="176,74,247,216" />
<Button Content="24" Height="25" Width="70" Margin="194,95,238,191" />
<Button Content="25" Height="30" Width="72" Margin="117,104,314,177" />
</Grid>