Jak mogę uzyskać pionowy pasek przewijania w moim ListBox?

84

W poniższym przykładzie mam ListBox z dziesiątkami nazw czcionek.

Pomyślałbym, że automatycznie będzie miał pionowy pasek przewijania, abyś mógł wybrać DOWOLNĄ czcionkę, nie tylko pierwszą z listy, ale tak nie jest.

Dodałem więc „ScrollViewer”, który umieszcza „obszar paska przewijania” po prawej stronie, ale w obszarze paska przewijania nie ma paska przewijania, aby można było przewijać (!).

Dlaczego pasek przewijania nie jest automatyczny i jak zmusić go, aby miał pasek przewijania?

<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
źródło

Odpowiedzi:

151

Problem z twoim rozwiązaniem polega na tym, że umieszczasz pasek przewijania wokół ListBox, gdzie prawdopodobnie chcesz umieścić go wewnątrz ListBox.

Jeśli chcesz wymusić pasek przewijania w ListBox, użyj dołączonej właściwości ScrollBar.VerticalScrollBarVisibility.

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

Ustawienie tej wartości na Auto spowoduje wyświetlenie paska przewijania w razie potrzeby.

JaredPar
źródło
3
W moim przypadku włożyłem też ListBoxwnętrze a ScrollVieweri ListBoxItemsrozciągały się tak szeroko, jak chcieli, na zewnątrz rozmiaru ListBox. Usunięcie ScrollVieweri ustawienie ScrollViewer.VerticalScrollBarVisibility="Visible"i ScrollViewer.HorizontalScrollBarVisibility="Disabled"załatwiło sprawę. Dziękuję za pomoc!
mandarynka
30

ListBoxjuż zawiera ScrollViewer. Domyślnie ScrollBarpojawi się, gdy jest więcej zawartości niż miejsca. Jednak niektóre kontenery zmieniają swój rozmiar, aby pomieścić swoją zawartość (np. StackPanel), Więc nigdy nie ma „więcej zawartości niż miejsca”. W takich przypadkach ListBoxzawsze zajmuje tyle miejsca, ile potrzeba na treść.

Aby obliczyć warunek posiadania większej ilości treści niż miejsca, należy znać rozmiar. Upewnij się, że masz ListBoxograniczony rozmiar, ustawiając rozmiar bezpośrednio w samym ListBoxelemencie lub z panelu hosta.

W przypadku, gdy panel hosta jest pionowy StackPaneli chcesz VerticalScrollBar, musisz ustawić wysokość na ListBoxsobie. W przypadku innych typów pojemników, na przykład Grid, ListBoxmoże być ograniczony przez pojemnik. Na przykład możesz zmienić oryginalny kod, aby wyglądał następująco:

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

Zwróć uwagę, że ważny jest nie tylko bezpośredni pojemnik. W twoim przykładzie bezpośrednim kontenerem jest a Grid, ale ponieważ Gridjest on zawarty przez a StackPanel, zewnętrzny StackPaneljest rozszerzany, aby pomieścić jego bezpośrednie dziecko Grid, tak że to dziecko może się rozwijać, aby pomieścić jego element podrzędny (the ListBox).

Jeśli ograniczysz wysokość w dowolnym momencie - ustawiając wysokość ListBox, ustawiając wysokość wewnętrznego Gridlub po prostu ustawiając zewnętrzny pojemnik a Grid- pionowy pasek przewijania pojawi się automatycznie za każdym razem, gdy jest zbyt wiele elementów listy do zmieścić się w kontroli.

yossharel
źródło
Użycie DockPanel jako kontenera nadrzędnego pomija potrzebę znajomości liczby elementów, które planujesz dodać jako podrzędne lub wstępnie zdefiniować dowolny atrybut wysokości. Dla każdego dziecka zdefiniuj DockPanel.Dock = Top. Dzięki temu Twoje „Scrollviewer-Childs” będą pokazywać swoje paski przewijania w razie potrzeby. Nie testowane ogólnie, zadziałało w moim przypadku. BR, Daniel
dba
1
TLDR: Zmień element nadrzędny z StackPanelna, Gridponieważ StackPanel zawsze rozwija się do wysokości swoich elementów podrzędnych.
Josh Noe
17

Dodałem „Wysokość” do mojego ListBox i ładnie dodałem pasek przewijania.

Edward Tanguay
źródło
8
Staraj się unikać używania właściwości wysokości i szerokości, ponieważ mogą one utrudniać zmiany na drodze. Lepiej wybierz rozwiązanie JaredPar.
Bryan Anderson
1
Robię to, ale po prostu umieszcza "obszar paska przewijania" po prawej stronie bez paska przewijania, a moja lista przechodzi przez dół mojego okna na całą wieczność, jak mogę powiedzieć pole listy (zatrzymaj się na dole okna )?
Edward Tanguay
15
Ponieważ znajduje się w StackPanel, szczęśliwie otrzymuje całą potrzebną przestrzeń, więc nie uważa, że potrzebuje paska przewijania.
Donnelle
4

Pasek przewijania jest dodawany do pola listy automatycznie, chyba że jego widoczność jest ustawiona na Ukryty. Ilekroć rozmiar elementów listy przekracza rozmiar, który można wyświetlić wewnątrz pola listy, w czasie wykonywania można zobaczyć pionowe lub poziome pole listy.

Paras
źródło
1

W moim przypadku liczba elementów w ListBox jest dynamiczna, więc nie chciałem używać właściwości Height. Zamiast tego użyłem MaxHeight i działa ładnie. Pasek przewijania pojawia się, gdy wypełnia miejsce, które dla niego przydzieliłem.

oldDavid
źródło
0

Miałem ten sam problem, miałem ComboBox, a następnie ListBox w StackPanel, a pasek przewijania dla ListBox nie był wyświetlany. Rozwiązałem to, umieszczając te dwa w DockPanel. Ustawiam ComboBox DockPanel.Dock = "Top" i pozwalam ListBox wypełnić pozostałą przestrzeń.

Bill Clyde
źródło
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
źródło