¿Cómo puedo obtener una barra de desplazamiento vertical en mi ListBox?


83

En el siguiente ejemplo, tengo un ListBox con docenas de nombres de fuentes.

Pensé que tendría automáticamente una barra de desplazamiento vertical para que pueda seleccionar CUALQUIER fuente, no solo las primeras en la lista, pero no es así.

Así que agregué un "ScrollViewer" y eso pone un "área de barra de desplazamiento" a la derecha, pero no hay barra de desplazamiento en el área de la barra de desplazamiento para que pueda desplazarse (!)

¿Por qué la barra de desplazamiento no es automática y cómo la fuerzo a tener una barra de desplazamiento?

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

Respuestas:


150

El problema con su solución es que está colocando una barra de desplazamiento alrededor de un ListBox donde probablemente quiera colocarlo dentro del ListBox.

Si desea forzar una barra de desplazamiento en su ListBox, use la propiedad adjunta ScrollBar.VerticalScrollBarVisibility.

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

Al establecer este valor en Auto, aparecerá la barra de desplazamiento según sea necesario.


3
En mi caso, había puesto el ListBoxinterior a ScrollViewertambién y ListBoxItemsse estiraban tanto como querían fuera del tamaño del ListBox. Quitar el ScrollViewery configurar ScrollViewer.VerticalScrollBarVisibility="Visible"y ScrollViewer.HorizontalScrollBarVisibility="Disabled"funcionó. ¡Gracias por tu ayuda!
mandarín

29

ListBoxya contiene ScrollViewer. De forma predeterminada ScrollBar, aparecerá cuando haya más contenido que espacio. Pero algunos contenedores se redimensionan para acomodar su contenido (por ejemplo StackPanel), por lo que nunca hay "más contenido que espacio". En tales casos, ListBoxsiempre se le da tanto espacio como sea necesario para el contenido.

Para calcular la condición de tener más contenido que espacio, se debe conocer el tamaño. Asegúrese de que ListBoxtenga un tamaño limitado, ya sea estableciendo el tamaño explícitamente en el ListBoxelemento mismo o desde el panel de host.

En caso de que el panel de host sea vertical StackPanely lo desee VerticalScrollBar, debe establecer la Altura sobre ListBoxsí mismo. Para otros tipos de contenedores, por ejemplo Grid, el contenedor ListBoxpuede restringirlos. Por ejemplo, puede cambiar su código original para que se vea así:

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

Tenga en cuenta que no es solo el contenedor inmediato lo que es importante. En su ejemplo, el contenedor inmediato es a Grid, pero debido a que Gridestá contenido por a StackPanel, el exterior StackPanelse expande para acomodar a su hijo inmediato Grid, de modo que ese hijo puede expandirse para acomodar a su hijo (el ListBox).

Si restringe la altura en cualquier punto, estableciendo la altura del ListBox, configurando la altura del interior Grido simplemente haciendo que el contenedor exterior sea a Grid, entonces una barra de desplazamiento vertical aparecerá automáticamente cada vez que haya demasiados elementos de la lista para encajar en el control.


El uso de un DockPanel como contenedor principal omite la necesidad de saber cuántos elementos planea agregar como secundarios o predefinir cualquier atributo de altura. Para cada niño, defina DockPanel.Dock = Top. Esto hace que sus "Scrollviewer-Childs" muestren sus barras de desplazamiento según sea necesario. No probado en general, funcionó en mi caso de uso. BR, Daniel
dba

1
TLDR: cambie su elemento padre de StackPanela Gridya que StackPanel siempre se expande a la altura de sus hijos.
Josh Noe

17

Agregué una "Altura" a mi ListBox y agregó muy bien la barra de desplazamiento.


8
Trate de evitar el uso de las propiedades de altura y ancho, ya que pueden dificultar los cambios en el camino. Es mejor optar por la solución de JaredPar.
Bryan Anderson

1
Hago eso, pero simplemente pone un "área de barra de desplazamiento" a la derecha sin barra de desplazamiento en sí, y mi lista pasa de la parte inferior de mi ventana a toda la eternidad, ¿cómo puedo saber el cuadro de lista (deténgase en la parte inferior de la ventana )?
Edward Tanguay

15
Debido a que está en un StackPanel, felizmente se le da todo el espacio que necesita, por lo que no cree que necesite una barra de desplazamiento.
Donnelle

4

La barra de desplazamiento se agrega al cuadro de lista automáticamente a menos que su visibilidad esté configurada como Oculto. Siempre que el tamaño de los elementos de la lista supere el que se puede mostrar dentro de un cuadro de lista, se puede ver un cuadro de lista vertical u horizontal durante el tiempo de ejecución.


1

En mi caso, la cantidad de elementos en ListBox es dinámica, por lo que no quería usar la propiedad Height. Usé MaxHeight en su lugar y funciona muy bien. La barra de desplazamiento aparece cuando llena el espacio que le he asignado.


0

Estaba teniendo el mismo problema, tenía un ComboBox seguido de un ListBox en un StackPanel y la barra de desplazamiento del ListBox no aparecía. Resolví esto colocando los dos en un DockPanel en su lugar. Configuré el ComboBox DockPanel.Dock = "Top" y dejé que ListBox llene el espacio restante.


0

Desplazador XAML ListBox - Windows 10 (UWP)

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.