2009-04-29 10 views
63

W poniższej wersji XAML do WPF ScrollViewer nie działa (wyświetla pasek przewijania, ale nie można przewijać, a zawartość wychodzi z okna na dół).Jak można uzyskać ScrollViewer do pracy wewnątrz StackPanel?

Mogę zmienić zewnętrzny StackPanel na Grid, który zadziała.

Jednak w mojej aplikacji, z której odtworzono poniższy kod, potrzebuję zewnętrznego zewnętrznego StackPanel. Co muszę zrobić do StackPanel, aby ScrollViewer pokazywał użyteczny pasek przewijania? np. VerticalAlignment = "Stretch" Wysokość = "Auto" nie działają.

<StackPanel> 
     <ScrollViewer> 
      <StackPanel> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
       <TextBlock Text="This is a test"/> 
      </StackPanel> 
     </ScrollViewer> 
</StackPanel> 

Odpowiedz

48

nie można bez ustalające wysokość StackPanel. Został zaprojektowany, aby rosnąć w nieskończoność w jednym kierunku. Radziłbym użyć innego Panel. Dlaczego "potrzebujesz", aby mieć zewnętrzny StackPanel?

+10

chciał stos rzeczy i stosując siatkę trzeba ręcznie zarządzać wszystkie wiersze i kolumny, ale DockPanel działa ładnie więc będę przełączyć się, że dzięki. –

+1

Zgadzam się z Edwardem. Z mojego doświadczenia wynika, owijając moje DataGrids w DockPanel, a następnie ustawiając DockPanel.Dock = "Top" dla każdego DataGrid działało świetnie. – CINCHAPPS

+2

Którą alternatywną kontrolę należy stosować w UWP? Nie ma DockPanel. Dziękuję Ci. –

49

To też mnie zaniepokoiło, wystarczy, że umieścisz swój stackpanel w przewijarce.

Ponadto, trzeba upewnić się, że właściwość CanContentScroll widza przewijania można ustawić na True, oto przykład:

<ScrollViewer Grid.Row="1" Margin="299,12,34,54" Name="ScrollViewer1" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" Height="195" CanContentScroll="True"> 
     <StackPanel Name="StackPanel1" OverridesDefaultStyle="False" Height="193" Width="376" VerticalAlignment="Top" HorizontalAlignment="Left"></StackPanel> 
    </ScrollViewer> 
+0

Gdzie jest właściwość CanContentScroll? Zobacz http://msdn.microsoft.com/en-us/library/system.windows.controls.scrollviewer_properties(v=VS.95).aspx – gideon

+2

Giddy> Zobacz ten link: - http://msdn.microsoft. com/en-us/library/ms612683.aspx –

+2

* Zwycięzca! * ....... –

8

Zauważ, że czasami można mieć StackPanel nie wiedząc. W moim przypadku miałem ten kod

<ScrollViewer> 
    <ItemsControl ItemsSource="{Binding Pages}"/> 
</ScrollViewer> 

który działał dobrze. "Strony", do których odnosi się bindowanie, były naprawdę odmiennymi, skomplikowanymi UserControlami i chciałem mieć tylko niektóre paski przewijania. Więc usunąłem ScrollViewer:

<ItemsControl ItemsSource="{Binding Pages}"/> 

I wtedy umieścić ScrollViewer jako górnego elementu na te z usercontrols gdzie chciałem im. Jednak to nie zadziałało. Treść właśnie spłynęła ze strony. Na początku nie sądziłem, że to pytanie/odpowiedź może mi pomóc, ale zdałem sobie sprawę, że domyślną jednostką ItemPanel elementu ItemsControl jest StackPanel. Więc rozwiązać mój problem, określając ItemsPanel że nie był StackPanel:

<ItemsControl ItemsSource="{Binding Pages}"> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Grid/> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
</ItemsControl> 
3

Rzeczywiście, sposób w jaki rozwiązał ten dileman było usunąć zewnętrzny panel stosu i zamiast ustawić ScrollViewer w pozycji chciałem wewnątrz głównej krata.

 <Grid Style="{StaticResource LayoutRootStyle}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="160"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions>   

    <!-- Vertical scrolling grid used in most view states -->  

     <ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto"> 
      <StackPanel Orientation="Horizontal"> 
       <GridView> 
       ... 
       </GridView> 
      </StackPanel> 
     </ScrollViewer>   
0

Przeniesienie Grid.Row = "1" z StackPanel do ScrollViewer całkowicie rozwiązało to dla mnie.

Miałem długą listę około 40 elementów do pokazania w StackPanel, ale tylko pierwsze 20 były wyświetlane.

<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto"> 
     <StackPanel x:Name="ContentPanel" Margin="12,0,12,0"> 
     <TextBlock Text="{Binding Line1}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/> 
     <TextBlock Text="" Margin="10,-2,10,0" Style="{StaticResource PhoneTextNormalStyle}" /> 
     ... 
     </StackPanel> 
    </ScrollViewer> 
3

Jak to działa:

<Window x:Class="TabControl.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
    xmlns:local="clr-namespace:TabControl" 
    Title="MainWindow" Height="300" 
    DataContext="{Binding RelativeSource={RelativeSource Self}}"   
    >  
<StackPanel> 
    <ScrollViewer Height="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type Border}},Path=ActualHeight}" > 
     <StackPanel > 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
      <TextBlock Text="This is a test"/>    <TextBlock Text="This is a test"/> 
     </StackPanel> 
    </ScrollViewer> 
</StackPanel> 

Wiążąc ScrollViewer w wysokości do okna za Wewnętrzna wysokość.

Logika zmiany rozmiaru polega na tym, że musimy podać wysokość dowolnego elementu lub zaprojektować widok, aby użyć wysokości renderowania.

wyjściowa:

Scrollbar in Stackpanel

+0

Jest trochę bliżej, ale nie do końca. Niektóre elementy sterowania, które są przodkami ScrollViewer, ale znajdują się między ramkami Border i ScrollViewer, mogą mieć margines (mój robi), a powiązanie z wartością ActualHeight tego nie wykryje. –

+0

@AlanMcBee tak, może być wiele możliwych przypadków, w których nie będzie to działać idealnie, ale jest to najbardziej podstawowy przypadek dla hierarchii kontroli, którą dałem rozwiązanie. Ale biorąc pod uwagę logikę, wszystko co musisz zrobić, to w większości przypadków zmienić typ przodka w wiązaniu i powinno to znów działać idealnie. Istotą poprawki było to, że w hierarchii znajdował się element UI, który pomógłby nam polegać na wysokości (niekoniecznie na granicy), logika może pozostać taka sama, o ile tylko można znaleźć wiarygodną wysokość. Mam nadzieję, że to ma sens, jeśli nie, opublikuj swój problem jako pytanie, postaram się pomóc. :) –

+0

'x: Typ' nie znaleziony. – Bigeyes

Powiązane problemy