Wie kann ich eine vertikale Bildlaufleiste in meiner ListBox erhalten?

82

Im folgenden Beispiel habe ich eine ListBox mit Dutzenden von Schriftnamen.

Ich hätte gedacht, dass es automatisch eine vertikale Bildlaufleiste gibt, so dass Sie JEDE Schriftart auswählen können, nicht nur die ersten in der Liste, aber nicht.

Also habe ich einen "ScrollViewer" hinzugefügt, der rechts einen "Bildlaufleistenbereich" einfügt, aber im Bildlaufleistenbereich befindet sich keine Bildlaufleiste, sodass Sie scrollen können (!).

Warum ist eine Bildlaufleiste nicht automatisch und wie erzwinge ich eine Bildlaufleiste?

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

Antworten:

144

Das Problem bei Ihrer Lösung besteht darin, dass Sie eine Bildlaufleiste um eine ListBox legen, wo Sie sie wahrscheinlich in die ListBox einfügen möchten.

Wenn Sie eine Bildlaufleiste in Ihrer ListBox erzwingen möchten, verwenden Sie die angehängte Eigenschaft ScrollBar.VerticalScrollBarVisibility.

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

Wenn Sie diesen Wert auf Auto setzen, wird die Bildlaufleiste nach Bedarf angezeigt.

JaredPar
quelle
3
In meinem Fall hatte ich auch das ListBoxInnere eingelegt ScrollViewerund die ListBoxItemsdehnten sich so weit, wie sie wollten, außerhalb der Größe des ListBox. Entfernen der ScrollViewerund Einstellung ScrollViewer.VerticalScrollBarVisibility="Visible"und ScrollViewer.HorizontalScrollBarVisibility="Disabled"hat den Trick gemacht. Danke für Ihre Hilfe!
Mandarin
29

ListBoxenthält bereits ScrollViewer. Standardmäßig wird das angezeigt ScrollBar, wenn mehr Inhalt als Speicherplatz vorhanden ist. Einige Container ändern jedoch die Größe, um ihren Inhalt aufzunehmen (z. B. StackPanel), sodass es nie "mehr Inhalt als Speicherplatz" gibt. In solchen Fällen wird dem ListBoximmer so viel Platz eingeräumt, wie für den Inhalt benötigt wird.

Um die Bedingung zu berechnen, dass mehr Inhalt als Speicherplatz vorhanden ist, sollte die Größe bekannt sein. ListBoxStellen Sie sicher, dass Ihre Größe eingeschränkt ist, indem Sie die Größe entweder explizit für das ListBoxElement selbst oder über das Hostfenster festlegen.

Wenn das Host-Panel vertikal ist StackPanelund Sie möchten VerticalScrollBar, müssen Sie die Höhe auf sich ListBoxselbst einstellen . Für andere Arten von Behältern, zum Beispiel Grid, die ListBoxdurch den Behälter eingeschränkt werden. Sie können beispielsweise Ihren ursprünglichen Code so ändern, dass er folgendermaßen aussieht:

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

Beachten Sie, dass nicht nur der unmittelbare Container wichtig ist. In Ihrem Beispiel ist der unmittelbare Container a Grid, aber da dieser Gridin a enthalten ist StackPanel, wird der äußere Container StackPanelerweitert, um sein unmittelbares Kind aufzunehmen Grid, sodass dieses Kind erweitert werden kann, um sein Kind (das ListBox) aufzunehmen.

Wenn Sie die Höhe an einem beliebigen Punkt einschränken - indem Sie die Höhe des ListBox, die Höhe des inneren Gridoder einfach den äußeren Container Gridfestlegen -, wird automatisch eine vertikale Bildlaufleiste angezeigt, wenn zu viele Listenelemente vorhanden sind in die Steuerung passen.

Yossharel
quelle
Wenn Sie ein DockPanel als übergeordneten Container verwenden, müssen Sie nicht wissen, wie viele Elemente Sie als untergeordnetes Element hinzufügen oder ein Höhenattribut vordefinieren möchten. Definieren Sie für jedes Kind DockPanel.Dock = Top. Dadurch zeigen Ihre "Scrollviewer-Childs" bei Bedarf ihre Bildlaufleisten an. Nicht allgemein getestet, es hat in meinem Anwendungsfall funktioniert. BR, Daniel
dba
1
TLDR: Ändern Sie Ihr übergeordnetes Element von StackPanelin, Gridda StackPanel immer auf die Höhe seiner untergeordneten Elemente erweitert wird.
Josh Noe
17

Ich habe meiner ListBox eine "Höhe" hinzugefügt und die Bildlaufleiste wurde schön hinzugefügt.

Edward Tanguay
quelle
8
Vermeiden Sie es, die Eigenschaften für Höhe und Breite zu verwenden, da dies Änderungen auf der Straße erschweren kann. Mit der Lösung von JaredPar sind Sie besser dran.
Bryan Anderson
1
Ich mache das, aber es wird nur ein "Bildlaufleistenbereich" ohne Bildlaufleiste rechts angezeigt, und meine Liste wird bis in alle Ewigkeit am unteren Rand meines Fensters angezeigt. Wie kann ich das Listenfeld erkennen (am unteren Rand des Fensters anhalten)? )?
Edward Tanguay
15
Weil es in einem Stackpanel, es ist fröhlich den ganzen Raum gegeben wird , es braucht, damit es nicht glaubt das es braucht eine Scrollbar.
Donnelle
4

Die Bildlaufleiste wird automatisch zum Listenfeld hinzugefügt, es sei denn, die Sichtbarkeit ist auf Versteckt eingestellt. Immer wenn die Größe von Listenelementen die überschreitet, die in einem Listenfeld angezeigt werden kann, wird während der Laufzeit ein vertikales oder horizontales Listenfeld angezeigt.

Paras
quelle
1

In meinem Fall ist die Anzahl der Elemente in der ListBox dynamisch, sodass ich die Height-Eigenschaft nicht verwenden wollte. Ich habe stattdessen MaxHeight verwendet und es funktioniert gut. Die Bildlaufleiste wird angezeigt, wenn sie den dafür vorgesehenen Platz ausfüllt.

oldDavid
quelle
0

Ich hatte das gleiche Problem, ich hatte eine ComboBox gefolgt von einer ListBox in einem StackPanel und die Bildlaufleiste für die ListBox wurde nicht angezeigt. Ich habe dieses Problem gelöst, indem ich die beiden stattdessen in ein DockPanel gestellt habe. Ich setze die ComboBox DockPanel.Dock = "Top" und lasse die ListBox den verbleibenden Platz füllen.

Bill Clyde
quelle
0

XAML ListBox Scroller - Windows 10 (UWP)

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

Mohammad Fazeli
quelle