如何在我的ListBox中添加垂直滚动条?

97
在下面的示例中,我有一个在其中有几十个字体名称的ListBox。
我本以为它会自动拥有一个垂直滚动条,以便您可以选择任何字体,而不仅仅是列表中的前几个,但实际上并没有。
所以我添加了一个“ScrollViewer”,这样右侧就会出现一个“滚动条区域”,但是在这个区域内没有滚动条,因此您无法进行滚动(!)。
为什么滚动条不是自动的,我该如何强制使其具有滚动条?
<StackPanel Name="stack1">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <ScrollViewer>
            <ListBox Grid.Row="0" Name="lstFonts" Margin="3"  ItemsSource="{x:Static Fonts.SystemFontFamilies}"/>
        </ScrollViewer>
    </Grid>
</StackPanel>
7个回答

166
你的解决方案问题在于你将滚动条放在ListBox周围,而你可能想要将其放在ListBox内部。
如果你想强制在ListBox中使用滚动条,请使用 VerticalScrollBarVisibility 附加属性。
<ListBox 
    ItemsSource="{Binding}" 
    ScrollViewer.VerticalScrollBarVisibility="Visible">
</ListBox>

将此值设置为自动将根据需要弹出滚动条。


3
在我的情况下,我也将ListBox放置在了一个ScrollViewer中,然后ListBoxItems的宽度超出了ListBox的大小。移除ScrollViewer并设置ScrollViewer.VerticalScrollBarVisibility="Visible"ScrollViewer.HorizontalScrollBarVisibility="Disabled"就解决了问题。 谢谢你的帮助! - mandarin

38

ListBox已经包含ScrollViewer。默认情况下,当内容超过空间时,ScrollBar会出现。但是有些容器会调整自己的大小以适应其内容(例如StackPanel),因此永远不存在“更多的内容比空间多”这种情况。在这种情况下,ListBox总是被赋予所需内容的尽可能大的空间。

为了计算是否存在超过空间的内容,必须知道尺寸大小。请确保ListBox有约束的大小,可以通过在ListBox元素本身上显式设置大小或从主机面板上设置来实现。

如果主机面板是垂直的StackPanel,并且您想要VerticalScrollBar,则必须在ListBox本身上设置Height。对于其他类型的容器,例如GridListBox可以受到容器的限制。例如,您可以将原始代码更改如下:

<Grid Name="grid1">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*"></RowDefinition>
            <RowDefinition Height="*"></RowDefinition>
        </Grid.RowDefinitions>
        <ListBox Grid.Row="0" Name="lstFonts" Margin="3"
                 ItemsSource="{x:Static Fonts.SystemFontFamilies}"/>
    </Grid>
</Grid>
请注意,仅仅关注直接容器是不够的。在您的示例中,直接容器是一个Grid,但由于该Grid被包含在StackPanel中,因此外部的StackPanel会扩展以适应其直接子级Grid,使得该子级能够扩展以适应它的子级(即ListBox)。
如果您在任何时候限制了高度——通过设置ListBox的高度,通过设置内部Grid的高度,或者仅仅通过将外部容器设置为Grid——那么每当列表项过多而无法适合控件时,垂直滚动条就会自动出现。

使用DockPanel作为父容器可以省略知道您计划添加多少个元素作为子元素或预定义任何高度属性的需要。对于每个子元素,定义DockPanel.Dock = Top。这使得您的“Scrollviewer-Childs”根据需要显示其滚动条。虽然没有经过全面测试,但在我的用例中确实有效。敬礼,丹尼尔。 - dba
1
简而言之:将父元素从“StackPanel”更改为“Grid”,因为StackPanel始终会扩展到其子元素的高度。 - Josh Noe

18

我给ListBox添加了"Height"属性,这样会很好地添加滚动条。


8
尽量避免使用高度和宽度属性,因为它们可能会使未来的更改变得困难。最好采用JaredPar的解决方案。 - Bryan Anderson
1
我这样做,但它只是在右边放置了一个“滚动条区域”,没有滚动条本身,我的列表向下延伸到窗口底部以至于无穷无尽,我该如何告诉列表框(停留在窗口底部)? - Edward Tanguay
15
因为它位于 StackPanel 中,所以它正在愉快地获得所有需要的空间,因此它不认为自己需要滚动条。 - Donnelle
这对我有用(我刚刚设置了MinHeight和MaxHeight而不是固定的Height)。谢谢。 - A. Dzebo

4

除非其可见性被设置为隐藏,否则滚动条会自动添加到列表框中。每当列表项的大小超过可以在列表框中显示的大小时,在运行时将出现垂直或水平列表框。


1
在我的情况下,ListBox 中的项目数是动态的,所以我不想使用 Height 属性。我改用 MaxHeight,效果很好。当填满我为它分配的空间时,滚动条会出现。

0

XAML ListBox Scroller - Windows 10(UWP)

XAML ListBox滚动条 - Windows 10 (UWP)

<Style TargetType="ListBox">
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Visible"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible"/>
</Style>


0
我曾经遇到过同样的问题,我的StackPanel中有一个ComboBox和一个ListBox,但是ListBox的滚动条没有显示出来。后来我将它们放在了一个DockPanel中,将ComboBox设置为DockPanel.Dock="Top",让ListBox填充剩余的空间,这样问题就解决了。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接