Как я могу получить вертикальную полосу прокрутки в моем ListBox?


84

В приведенном ниже примере у меня есть 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>

Ответы:


151

Проблема с вашим решением заключается в том, что вы помещаете полосу прокрутки вокруг ListBox, где вы, вероятно, хотите поместить ее внутри ListBox.

Если вы хотите принудительно использовать полосу прокрутки в ListBox, используйте присоединенное свойство ScrollBar.VerticalScrollBarVisibility.

<ListBox 
    ItemsSource="{Binding}" 
    ScrollViewer.VerticalScrollBarVisibility="Visible">
</ListBox>

Установка этого значения в Auto будет вызывать всплывающую полосу прокрутки по мере необходимости.


3
В моем случае я тоже положил ListBoxвнутрь, ScrollViewerи ListBoxItemsони растягивались настолько широко, насколько хотели, за пределы размера ListBox. Удаление ScrollViewerи установка ScrollViewer.VerticalScrollBarVisibility="Visible"и ScrollViewer.HorizontalScrollBarVisibility="Disabled"сделали свое дело. Спасибо за помощь!
мандарин

30

ListBoxуже содержит ScrollViewer. По умолчанию ScrollBarбудет отображаться, когда содержимого больше, чем места. Но некоторые контейнеры изменяют размер, чтобы вместить их содержимое (например StackPanel), поэтому «содержимого больше, чем места» не бывает. В таких случаях ListBoxвсегда предоставляется столько места, сколько необходимо для содержимого.

Размер должен быть известен, чтобы вычислить условие наличия большего количества содержимого, чем пространства. Убедитесь, что у вас ListBoxограниченный размер, задав размер явно в самом ListBoxэлементе или на главной панели.

В случае, если основная панель вертикальная, StackPanelи вы хотите, VerticalScrollBarвы должны установить высоту ListBoxсама по себе. Для других типов контейнеров, например Grid, контейнер ListBoxможет быть ограничен. Например, вы можете изменить исходный код, чтобы он выглядел так:

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

Обратите внимание, что важен не только непосредственный контейнер. В вашем примере непосредственным контейнером является a Grid, но поскольку Gridон содержится в a StackPanel, внешний StackPanelрасширяется для размещения своего непосредственного дочернего элемента Grid, так что этот дочерний элемент может расширяться для размещения своего дочернего элемента ( ListBox).

Если вы ограничите высоту в любой точке - установив высоту ListBox, установив высоту внутреннего Gridили просто сделав внешний контейнер a Grid- тогда вертикальная полоса прокрутки появится автоматически каждый раз, когда есть слишком много элементов списка для вписывается в контроль.


Использование DockPanel в качестве родительского контейнера исключает необходимость знать, сколько элементов вы планируете добавить в качестве дочерних или предварительно определить какой-либо атрибут высоты. Для каждого дочернего элемента определите DockPanel.Dock = Top. Это заставит ваши "Scrollviewer-Childs" показывать свои полосы прокрутки по мере необходимости. В целом не тестировался, в моем случае он работал. BR, Daniel
dba

1
TL; DR : измените родительский элемент с StackPanelна, Gridпоскольку StackPanel всегда расширяется до высоты своих дочерних элементов.
Джош Ной

17

Я добавил «Высота» в свой ListBox, и он красиво добавил полосу прокрутки.


8
Старайтесь избегать использования свойств высоты и ширины, поскольку они могут затруднить внесение изменений в будущем. Вам лучше воспользоваться решением JaredPar.
Брайан Андерсон,

1
Я делаю это, но он просто помещает «область полосы прокрутки» вправо без самой полосы прокрутки, и мой список идет вниз за нижнюю часть моего окна на всю вечность, как я могу сказать поле списка (остановитесь в нижней части окна )?
Эдвард Тангуай

15
Поскольку он находится в StackPanel, ему с радостью предоставляется все необходимое пространство, поэтому он не думает, что ему нужна полоса прокрутки.
Donnelle

4

Полоса прокрутки добавляется в список автоматически, если для ее видимости не установлено значение «Скрытый». Каждый раз, когда размер элементов списка превышает один, который может отображаться внутри окна списка, вертикальный или горизонтальный список можно увидеть во время выполнения.


1

В моем случае количество элементов в ListBox является динамическим, поэтому я не хотел использовать свойство Height. Вместо этого я использовал MaxHeight, и он отлично работает. Полоса прокрутки появляется, когда заполняет выделенное для нее пространство.


0

У меня была та же проблема: у меня был ComboBox, за которым следовало ListBox в StackPanel, а полоса прокрутки ListBox не отображалась. Я решил это, вместо этого поместив их в DockPanel. Я установил ComboBox DockPanel.Dock = "Top" и позволил ListBox заполнить оставшееся пространство.


0

Прокрутка XAML ListBox - Windows 10 (UWP)

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.