WPF: ItemsControl mit Bildlaufleiste (ScrollViewer)

128

Ich habe dieses kleine "Tutorial" zum Hinzufügen einer Bildlaufleiste zu einem ItemsControl befolgt und es funktioniert in der Designer-Ansicht, jedoch nicht, wenn ich das Programm kompiliere und ausführe (nur die ersten Elemente werden angezeigt und keine Bildlaufleiste, um mehr anzuzeigen - sogar wenn VerticalScrollbarVisibility auf "Sichtbar" anstelle von "Auto" gesetzt ist).

Irgendeine Idee, wie man das löst?


Dies ist der Code, mit dem ich meine Elemente anzeige (normalerweise arbeite ich mit Datenbindung, aber um die Elemente in meinem Designer anzuzeigen, habe ich sie manuell hinzugefügt):

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

Und das ist meine Vorlage:

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

Antworten:

261

Um eine Bildlaufleiste für eine zu erhalten ItemsControl, können Sie diese folgendermaßen hosten ScrollViewer:

<ScrollViewer VerticalScrollBarVisibility="Auto">
  <ItemsControl>
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
    <uc:UcSpeler />
  </ItemsControl>
</ScrollViewer>
Oskar
quelle
16
Es ist so offensichtlich, wenn Sie es sehen ... Da ich von Windows Forms komme, stecke ich oft in der falschen Denkweise fest. Es scheint, dass WPF viele Fehler korrigiert ... +1.
Christoffer Lette
3
Vielen Dank - sehr hilfreich. Ich stimme Lette zu, dass mein WinForms-Gehirn dies zunächst nicht "versteht".
matt
1
Ich habe es gerade hier versucht und es hat immer noch nicht funktioniert. Das ItemsControl fließt direkt aus seinem übergeordneten Container und es ist überhaupt keine ScrollBar sichtbar.
Ristogod
8
@Ristogod Wenn Sie den ScrollViewer in etwas hosten, dessen Inhalt so stark wächst, wie es erforderlich ist, z. B. in einem StackPanel, funktioniert das Scrollen nicht. Was ist der übergeordnete Container? Versuchen Sie, eine feste Höhe entweder im ScrollViewer oder im übergeordneten Element festzulegen. Hilft das?
Oskar
4
@ Rod Sie können den ScrollViewer in einem DockPanel oder einem Grid anstelle eines StackPanels hosten, um dies zu erreichen.
Oskar
79

Sie müssen die Steuerelementvorlage anstelle von ItemsPanelTemplate ändern:

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

Möglicherweise funktioniert Ihr Code nicht, da StackPanel über eine eigene Bildlauffunktion verfügt. Versuchen Sie, die StackPanel.CanVerticallyScroll- Eigenschaft zu verwenden.

Andrey Shvydky
quelle
1
Die StackPanel CanVerticallyScroll-Eigenschaft hat leider nicht funktioniert.
Xuntar
StackPanel CanVerticallyScroll hat nicht funktioniert, aber das hier angegebene Codebeispiel hat bei mir funktioniert. Danke
Souvik Basu
Das funktioniert. Ich suche nach einem Scrollviewer von innen statt von außen, weil github.com/punker76/gong-wpf-dragdrop dies erfordert.
HelloSam
3

Legen Sie Ihren ScrollViewer in ein DockPanel und legen Sie die DockPanel MaxHeight-Eigenschaft fest

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