WPF: ItemsControl con barra de desplazamiento (ScrollViewer)

128

Seguí este pequeño "tutorial" sobre cómo agregar una barra de desplazamiento a un ItemsControl, y funciona en la vista del Diseñador, pero no cuando compilo y ejecuto el programa (solo aparecen los primeros elementos y ninguna barra de desplazamiento para ver más, incluso cuando VerticalScrollbarVisibility se establece en "Visible" en lugar de "Auto").

¿Alguna idea sobre cómo resolver esto?


Este es el código que uso para mostrar mis elementos (normalmente trabajo con Databinding, pero para ver los elementos en mi Diseñador los agregué manualmente):

<ItemsControl x:Name="itemCtrl" Style="{DynamicResource UsersControlStyle}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical" HorizontalAlignment="Center" VerticalAlignment="Top">
            </StackPanel>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
</ItemsControl>

Y esta es mi plantilla:

<Style x:Key="UsersControlStyle" TargetType="{x:Type ItemsControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ItemsControl}">
                <Border SnapsToDevicePixels="true" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                    <ScrollViewer VerticalScrollBarVisibility="Visible">
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Xuntar
fuente

Respuestas:

261

Para obtener una barra de desplazamiento para un ItemsControl, puede alojarlo de ScrollVieweresta manera:

<ScrollViewer VerticalScrollBarVisibility="Auto">
  <ItemsControl>
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
  </ItemsControl>
</ScrollViewer>
Oskar
fuente
16
Es tan obvio cuando lo ves ... Como vengo de Windows Forms, a menudo me encuentro atrapado en la mentalidad incorrecta. Parece que WPF endereza muchos errores ... +1.
Christoffer Lette
3
Gracias, muy útil. Estoy de acuerdo con Lette en que mi cerebro WinForms no "entiende" esto inicialmente.
itsmatt
1
Acabo de probar esto aquí y todavía no funcionó. ItemsControl fluye directamente desde su contenedor principal y no hay barra de desplazamiento visible en absoluto.
Ristogod
8
@Ristogod Si aloja el ScrollViewer dentro de algo que permite que su contenido crezca tanto como sea necesario, por ejemplo, un StackPanel, el desplazamiento no funcionará. ¿Cuál es el contenedor principal? Intente establecer una altura fija en el ScrollViewer o en el padre, ¿eso ayuda?
Oskar
44
@Rod Puede alojar el ScrollViewer en un DockPanel o un Grid en lugar de un StackPanel para lograr esto.
Oskar
79

Debe modificar la plantilla de control en lugar de ItemsPanelTemplate:

<ItemsControl >
    <ItemsControl.Template>
        <ControlTemplate>
            <ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}">
                <ItemsPresenter />
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

Tal vez, su código no funciona porque StackPanel tiene su propia funcionalidad de desplazamiento. Intente utilizar la propiedad StackPanel.CanVerticallyScroll .

Andrey Shvydky
fuente
1
Me temo que la propiedad StackPanel CanVerticallyScroll no funcionó.
Xuntar
StackPanel CanVerticallyScroll no funcionó, pero el ejemplo de código que se proporciona aquí funcionó para mí. Gracias
Souvik Basu
Esto funciona. Estoy buscando hacer scrollviewer adentro en lugar de afuera, porque github.com/punker76/gong-wpf-dragdrop lo requiere.
HolaSam
3

Coloque su ScrollViewer en un DockPanel y configure la propiedad DockPanel MaxHeight

[...]
<DockPanel MaxHeight="700">
  <ScrollViewer VerticalScrollBarVisibility="Auto">
   <ItemsControl ItemSource ="{Binding ...}">
     [...]
   </ItemsControl>
  </ScrollViewer>
</DockPanel>
[...]
Patatrack
fuente