【问题标题】:Using WrapPanel and ScrollViewer to give a multi-column Listbox in WPF使用 WrapPanel 和 ScrollViewer 在 WPF 中提供多列列表框
【发布时间】:2010-10-28 19:54:22
【问题描述】:

我正在制作一个简单的 LOB 应用程序,它从 XML 文件加载数据并将其显示在带有几个按钮的列表中以供编辑。

在我的第一次尝试中,一切都很好,只是列表在一个长列中向下滚动。我希望将数据包装起来,以便在窗口底部开始第二列,依此类推——如果您调整窗口大小,数据应该相应地调整大小。

首先,我只是将 ListBox 放在 ScrollViewer 中。这没有任何区别。

然后,我在 ItemTemplate 中添加了 WrapPanel。在这一点上,我得到了一个水平的长行,但它从来没有换到第二行,尽管我设置了 ScrollViewer.Horizo​​ntalScrollbar=disabled。

我在各种博客和论坛上搜索了网络,但看不出建议和我的代码(包括在下面)之间的区别。任何提示将不胜感激。

<Window x:Class="MyApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="My App" Height="300" Width="400"
        FocusManager.FocusedElement="{Binding ElementName=eventsList}">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="auto" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
                <ScrollViewer Grid.Row="0" Grid.Column="0"     HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
            <ListBox Name="eventsList">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel />
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
            </ListBox>
        </ScrollViewer>

        <StackPanel Grid.Row="1" Grid.Column="0" Orientation="Horizontal"     HorizontalAlignment="Center" Visibility="Collapsed">
            <Button Name="action1Button" />
            <Button Name="action2Button" />
            <Button Name="action3Button" />
        </StackPanel>
    </Grid>
</Window>

【问题讨论】:

    标签: wpf data-binding xaml listbox


    【解决方案1】:

    您似乎走在了正确的轨道上:将 ListBox 中的 ItemsPanelTemplate 替换为 WrapPanel,将 WrapPanel 的 Orientation 设置为 Vertical,并将 ScrollViewer.VerticalScrollBar 设置为 Disabled 应该是您需要做的所有事情。

    这对我有用:

    <Window x:Class="ScrollingWrapPanel.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <ListBox ScrollViewer.VerticalScrollBarVisibility="Disabled">
                <ListBox.ItemsPanel>
                    <ItemsPanelTemplate>
                        <WrapPanel IsItemsHost="True" Orientation="Vertical"/>
                    </ItemsPanelTemplate>
                </ListBox.ItemsPanel>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Red"/>
                </ListBoxItem>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Orange"/>
                </ListBoxItem>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Yellow"/>
                </ListBoxItem>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Green"/>
                </ListBoxItem>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Blue"/>
                </ListBoxItem>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Indigo"/>
                </ListBoxItem>
                <ListBoxItem>
                    <Rectangle Width="80" Height="80" Margin="10" Fill="Violet"/>
                </ListBoxItem>
            </ListBox>
        </Grid>
    </Window>
    

    这应该会导致它垂直渲染一整列,换行,然后继续下一列,根据需要水平滚动(但不是垂直),如图所示:

    这个实现的关键是

    1. 在 WrapPanel 上设置 Orientation="Vertical" 以使内容垂直而不是水平缠绕,并且
    2. 在 ListBox 上设置 ScrollViewer.VerticalScrollBarVisibility="Disabled" 以便 ScrollViewer 知道将其高度限制为可用空间。

    【讨论】:

    • 我错过了 ScrollViewer.VerticalScrollBarVisibility="Disabled"。谢谢!!!!!!!!!!!!!!!!!!
    • 3 年后...这篇文章还是很有帮助的,谢谢!
    • 有用 8 年后,如果你只想垂直滚动换行面板:ScrollViewer.Horizo​​ntalScrollBarVisibility="Disabled">
    【解决方案2】:

    我相信要做到这一点,您需要编写自定义代码 - 您在覆盖 ItemsPanelTemplate 方面有正确的想法,但 WrapPanel 不会按照您想要的方式订购东西 - 它会按以下方式订购东西:

    A B C D
    E F G H
    I J K L
    

    而你可能想要它:

    A D G J
    B E H K
    C F I L
    

    另外,通过将它放在 ScrollViewer 中,就像告诉它它有一个无限大小的屏幕,所以结果只会是一行(因为 ScrollViewer 会给它所需的空间)。编写面板并不难,它基本上只有两个功能(测量和排列)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-06
      • 1970-01-01
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多