18

我需要垂直(使用 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 的方向设置为“垂直”:

结果- 我的项目是垂直排序的,但没有分布在多个列上。

这是我希望渲染项目的方式:

我真的很想避免编写代码来监视控件大小以根据其大小创建/删除列。

4

5 回答 5

10

如果您设置OrientationVertical您还应该设置渲染高度。例如对WrapPanel, Height="150"

于 2012-07-05T13:18:25.633 回答
3

终于得到了一些有用的东西,但它需要代码。当您说我们需要调整 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>

这是代码隐藏:

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

}
于 2012-07-06T12:49:00.033 回答
2

WrapPanel如果没有定义它,这种行为是不可能的Height

您可以使用的一种替代方法是 a Grid, where inOnLoadedOnSizeChanged,它计算可以容纳多少列,然后设置 Grid 的 Row/Column 定义和代码隐藏中每个对象的Grid.Row/ 。Grid.Column它并不漂亮,但它应该相当简单,并且可以工作。

另一种选择是创建您自己的自定义面板,按照您的需要排列项目。您甚至可以在网上找到已经做到这一点的东西

于 2012-07-05T18:03:06.870 回答
1

使用 a 执行此操作的唯一方法WrapPanel是显式设置Height.

看起来您希望项目均匀地分布在列上,左列最多比右列多一个项目。如果那是您正在寻找的,那么您需要创建自己的自定义面板。看看这个,看看如何开始。您将需要 ItemWidth 和 ItemHeight 依赖属性,并使用 ItemWidth 和可用宽度计算可以拥有的列数。

于 2012-07-05T17:54:26.743 回答
0

禁用垂直滚动条。这告诉 WPF 使用水平空间。
<WrapPanel Orientation="Vertical" ScrollViewer.VerticalScrollBarVisibility="Disabled" />

Frode,试试这个(VS2017 .NET 4.7.2):

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfApp1.MainWindow" Title="Wrap Panel Test" Height="100" Width="250">
    <ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Disabled">
        <WrapPanel Orientation="Vertical">
            <Button Width="100" Content="1" />
            <Button Width="100" Content="2" />
            <Button Width="100" Content="3" />
            <Button Width="100" Content="4" />
            <Button Width="100" Content="5" />
        </WrapPanel>
    </ScrollViewer>
</Window>

包装面板演示

于 2020-03-03T03:51:38.353 回答