Обернуть панель с "видом" двухсторонней упаковки - PullRequest
0 голосов
/ 02 октября 2011

Итак, у меня есть обертка, которая обернута вертикально. Элементы добавляются во время выполнения, но все эти элементы (пользовательские элементы управления) имеют разную ширину, и поскольку оберточная оболочка оборачивается вертикально, она укладывает их вниз, а когда они закрывают вертикальное пространство, они переносятся в следующий столбец. НО мне нужен «вид» двухсторонней упаковки, то есть я добавил первый элемент шириной 200 пикселей, затем я добавил второй элемент шириной около 50 пикселей, но когда я добавляю третий элемент размером около 100 пикселей width Я хочу, чтобы он не переходил к следующему ряду, а размещал себя в этом свободном месте, оставляя там элемент управления 50px, в зависимости от того элемента управления 200px сверху (который оставляет пространство 150px и элемент управления 100px явно помещается). Конечно, когда он не подходит, он переносится в следующий ряд, и это все в порядке.

Вот изображения, чтобы прояснить это (не могу загрузить их здесь):

Вот что происходит: изображение 1

И вот чего я хочу: изображение 2


Извините за мой английский, это не мой основной язык. Надеюсь, вы поймете мой вопрос.

Ответы [ 2 ]

0 голосов
/ 02 октября 2011

Ну, я сделал это. Просто написал пользовательскую оболочку с нужным мне поведением. Вот оно:

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;
}
}
0 голосов
/ 02 октября 2011

Вы определенно не можете использовать одну панель для этого! Вы можете использовать стековую панель, куда нужно вставить несколько динамических оберточных панелей с горизонтальной ориентацией, чтобы иметь нужное вам поведение «столбца»

...