Fixed Wrap panel wpf

*爱你&永不变心* 提交于 2020-01-12 04:49:09

问题


i am working on wpf window that show list of items next each other with wrapping, i have tried to use WrapPanel in this way:

<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>

and this is the result:

Actually this result is unsatisfactory for me because if you imagine the WrapPanel as grid(rows and columns) you will find that there is no columns, but there are fixed size rows. i need to make WarpPanel or some control else without columns too, look at this imaginary image:

notice that there is no rows and no columns. this is what i wanna make.

anybody have ideas to solve this issue?


回答1:


You could write your own custom Panel class. There are some tutorials on the web, simply google "wpf custom panel".

It boils down to overriding the MeasureOverride and ArrangeOverride methods.

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;
    }
}

UPDATE: The following simple custom Panel might more or less do what you want.

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;
    }
}



回答2:


You Can Either use Canvas:

Or Use Grid and set the Margin of each Buttons according to requirenment

     <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>


来源:https://stackoverflow.com/questions/15875081/fixed-wrap-panel-wpf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!