Подтвердить что ты не робот

Элементы списка Вертикально на WrapPanel и используйте несколько столбцов

Мне нужно перечислить элементы (все одинакового размера) по вертикали (с помощью ScrollViewer). Я хочу, чтобы элементы распространялись через столбцы x, если контейнер достаточно велик, чтобы отображать x столбцов

Я сначала попробовал, чтобы:

<ScrollViewer>
    <toolkit:WrapPanel Orientation="Horizontal" ItemHeight="30" ItemWidth="100">
        <Button Content="1" />
        <Button Content="2" />
        <Button Content="3" />
        <Button Content="4" />
        <Button Content="5" />
    </toolkit:WrapPanel>
</ScrollViewer>

Результат. WrapPanel работает так, как я хочу, но мои объекты упорядочены с "слева направо" (не вертикально

Затем я попытался установить ориентацию WrapPanel на " Вертикальный":

Результат. Мои элементы упорядочены по вертикали, но не распределены по нескольким столбцам.

Вот как я хочу, чтобы объекты отображались:

Мне бы очень хотелось избежать необходимости писать код, контролирующий размер элемента управления для создания/удаления столбцов в зависимости от его размера.

4b9b3361

Ответ 1

Если вы установите Orientation на Vertical, вы также должны установить высоту рендеринга. Например, WrapPanel, Height="150".

Ответ 2

Наконец-то получил что-то, что работает, но ему нужен код. Я согласен со всеми вами, когда вы говорите, что нам нужно изменить размер WrapPanel, чтобы это сработало. Вот мое решение:

<ScrollViewer x:Name="scroll1" SizeChanged="ScrollViewer_SizeChanged" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
    <toolkit:WrapPanel x:Name="wp1" Orientation="Vertical" VerticalAlignment="Top" HorizontalAlignment="Left" ItemHeight="30" ItemWidth="250" >
        <Button Content="1" />
        <Button Content="2" />
        <Button Content="3" />
        <Button Content="4" />
        <Button Content="5" />
        <Button Content="6" />
        <Button Content="7" />
        <Button Content="8" />
    </toolkit:WrapPanel>
</ScrollViewer>

Вот код CodeBehind:

private void ScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e)
{
    // Stupid magical number because ViewPortHeight is sometimes not accurate
    Double MAGICALNUMBER = 2;

    // Ensure ViewPortSize is not 0
    if (scroll1.ViewportWidth <= MAGICALNUMBER || scroll1.ViewportHeight <= MAGICALNUMBER)
        return;

    Size contentSize = new Size(scroll1.ViewportWidth - MAGICALNUMBER, scroll1.ViewportHeight - MAGICALNUMBER);
    Size itemSize = new Size(wp1.ItemWidth, wp1.ItemHeight);

    Size newSize = CalculateSizeBasedOnContent(contentSize, wp1.Children.Count, itemSize);

    wp1.Width = newSize.Width;
    wp1.Height = newSize.Height;
}


private Size CalculateSizeBasedOnContent(Size containerSize, int itemsCount, Size itemSize)
{

    int iPossibleColumns = (int)Math.Floor(containerSize.Width / itemSize.Width);
    int iPossibleRows = (int)Math.Floor(containerSize.Height / itemSize.Height);

    // If all items can fit in first column without scrolling (or if container is narrow than the itemWidth)
    if (itemsCount <= iPossibleRows || containerSize.Width < itemSize.Width)
    return new Size(itemSize.Width, (itemsCount * itemSize.Height));

    // If all items can fit in columns without scrollbar
    if (iPossibleColumns * iPossibleRows > itemsCount)
    {
    int columnsNeededForDisplay = (int)Math.Ceiling((itemsCount/(Double) iPossibleRows));
    return new Size(columnsNeededForDisplay * itemSize.Width, containerSize.Height);
    }

    // Here scrolling is needed even after spreading in columns
    int itemsPerColumn = (int)Math.Ceiling(wp1.Children.Count / (Double)iPossibleColumns);
    return new Size(containerSize.Width, itemsPerColumn * itemSize.Height);

}

Ответ 3

Такое поведение невозможно при использовании WrapPanel без определения его Height

Один из вариантов, который вы можете использовать, - это Grid, где в OnLoaded и OnSizeChanged он вычисляет, сколько столбцов будет соответствовать, затем задает определения Row/Column для Grid и Grid.Row/Grid.Column каждого объекта в коде. Это не очень, но это должно быть довольно просто собрать и работать.

Другой вариант - создать собственную пользовательскую панель, которая упорядочивает элементы, как вы хотите. Возможно, вы даже сможете найти что-то доступное в Интернете, которое уже делает это

Ответ 4

Единственный способ сделать это с помощью WrapPanel - это явно установить Height.

Похоже, вы хотите, чтобы элементы были равномерно распределены по столбцам с левым столбцом, имеющим не более одного элемента, чем столбец справа. Если это то, что вы ищете, вам нужно создать свою собственную панель. Посмотрите этот, чтобы узнать, как начать работу. Вам понадобятся свойства зависимости ItemWidth и ItemHeight и подсчитайте, сколько столбцов вы можете использовать с помощью ItemWidth и доступной ширины.