修复了Wrap面板wpf

时间:2013-04-08 08:58:48

标签: wpf wrappanel

我正在开发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>

这就是结果:

enter image description here

实际上这个结果对我来说并不令人满意,因为如果你想象WrapPanel为网格(行和列),你会发现没有列,但是有固定大小的行。我需要制作WarpPanel或其他没有列的控件,看看这个虚构的图像:

enter image description here

注意没有行,也没有列。这就是我想做的事。

有人有想法解决这个问题吗?

2 个答案:

答案 0 :(得分:9)

您可以编写自己的自定义Panel类。网上有一些教程,只需谷歌“wpf自定义面板”。

归结为覆盖MeasureOverrideArrangeOverride方法。

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>