0

所以我有一个垂直包裹的包裹板。这些项目是在运行时添加的,但是所有这些项目(用户控件)都有不同的宽度,并且由于包装面板是垂直包装的,因此它将它们向下堆叠,当它们覆盖垂直空间时,它们会包装到下一列。但是我需要的是“一种”双向包装,即我添加了第一个宽度为 200 像素的项目,然后我添加了第二个宽度为 50 像素的项目,但是当我添加第三个项目时,它的宽度为 100 像素宽度我希望它不要转到下一行,而是将自身放置在那个空闲的位置,根据顶部的 200 像素控件(留下 150 像素的空间和 100 像素的控件显然适合)。当然,当它不适合时,它会换行到下一行,这一切都可以。

这是一张图片来澄清这一点(不能在这里上传):

这就是发生的事情: 图 1

这就是我想要的: 图片 2


对不起我的英语,它不是我的主要语言。我希望你能理解我的问题。

4

2 回答 2

0

嗯,我做到了。刚刚用我想要的行为编写了一个自定义包装面板。

这里是:

public class TwoWayWrapPanel : Panel
{
int _rowCount = 0;

public int RowCount
{
    get { return _rowCount; }
    set { _rowCount = value; }
}

protected override Size MeasureOverride(Size availableSize)
{
    Size resultSize = new Size(0, 0);
    double columnWidth = 0;
    double usedSpace = 0;
    double nullX = 0;
    double currentX = 0;
    double currentY = 0;
    bool isFirst = true;
    int row = 0;

    foreach (UIElement child in Children)
    {
        child.Measure(availableSize);

        if (isFirst)
        {
            columnWidth = child.DesiredSize.Width;
            resultSize.Width += columnWidth;
            currentY += child.DesiredSize.Height;
            row++;
            isFirst = false;
        }
        else
        {
            if (columnWidth >= usedSpace + child.DesiredSize.Width & _rowCount > 1)
            {
                currentX = nullX + usedSpace;
                usedSpace += child.DesiredSize.Width;
            }
            else
            {
                row++;

                if (row + 1 > _rowCount | child.DesiredSize.Width > columnWidth)
                {
                    row = 0;
                    currentX = nullX + columnWidth;
                    nullX = currentX;
                    usedSpace = 0;
                    columnWidth = child.DesiredSize.Width;
                    currentY = child.DesiredSize.Height;
                    row++;
                    resultSize.Width += columnWidth;
                }
                else
                {
                    currentY += child.DesiredSize.Height;
                    currentX = nullX;
                    usedSpace = child.DesiredSize.Width;
                }
            }
        }
    }

    return resultSize;
}

protected override Size ArrangeOverride(Size finalSize)
{
    double columnWidth = 0;
    double usedSpace = 0;
    double nullX = 0;
    double currentX = 0;
    double currentY = 0;
    bool isFirst = true;
    int row = 0;

    foreach (UIElement child in Children)
    {
        //First item in the collection
        if (isFirst)
        { 
            child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
            columnWidth = child.DesiredSize.Width;
            currentY += child.DesiredSize.Height;
            row++;
            isFirst = false;
        }
        else
        {
            //Current item fits so place it in the same row
            if (columnWidth >= usedSpace + child.DesiredSize.Width & _rowCount > 1)
            {
                currentX = nullX + usedSpace;
                child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                usedSpace += child.DesiredSize.Width;
            }
            else
            {
                row++;

                //The row limit is reached or the item width is greater than primary item width. Creating new column
                if (row + 1 > _rowCount | child.DesiredSize.Width > columnWidth)
                {
                    row = 0;
                    currentY = 0;
                    currentX = nullX + columnWidth;
                    nullX = currentX;
                    usedSpace = 0;
                    child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                    columnWidth = child.DesiredSize.Width;
                    currentY += child.DesiredSize.Height;
                    row++;
                }
                //Item doesn't fit. Adding to the new row in the same column
                else
                {
                    usedSpace = 0;
                    currentY += child.DesiredSize.Height;
                    currentX = nullX;
                    child.Arrange(new Rect(currentX, currentY, child.DesiredSize.Width, child.DesiredSize.Height));
                    usedSpace += child.DesiredSize.Width;
                }
            }
        }
    }

    return finalSize;
}
}
于 2011-10-02T18:57:01.680 回答
0

您绝对不能使用单个面板来完成此操作!您可以使用堆栈面板在其中插入多个具有水平方向的动态包装面板以获得您需要的“列”行为

于 2011-10-02T10:23:51.873 回答