2009-07-15 14 views
26

Używam kontrolki scrollviewer wokół mojego panelu stosu, który zawiera ItemsControl. Kiedy w ItemControl znajduje się wiele przedmiotów, należy przewijać, ale z jakiegoś powodu po prostu przecinają przedmioty. Oto kod:ScrollViewer nie przewija w WPF

<StackPanel> 
    <ScrollViewer CanContentScroll="True" VerticalScrollBarVisibility="Visible"> 
     <ItemsControl Name="icEvents" Width="Auto" Height="100" Background="AliceBlue" 
         ItemsSource="{Binding Path=EventSources}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <StackPanel> 
         <TextBlock Text="Source:"/> 
         <TextBlock Text="{Binding Path=Source}" /> 
         <TextBlock Text="Original Source:"/> 
         <TextBlock Text="{Binding Path=OriginalSource}" /> 
        </StackPanel> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate> 
     </ItemsControl> 
    </ScrollViewer> 
</StackPanel> 

Odpowiedz

40

Spróbuj siatkę wokół ScrollViwer zamiast StackPanel. Myślę, że StackPanel zapewni taką samą wysokość, jakiej oczekuje wewnętrzna zawartość, więc tutaj Scrollviwer nie działa poprawnie, ponieważ jej wysokość nie jest ograniczona przez kontrolę nad nią.

Możesz zrozumieć problem z poniższego przykładu.

<StackPanel> 
    <ScrollViewer> 
     <ItemsControl > 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
     </ItemsControl> 
    </ScrollViewer> 
</StackPanel> 

Powyższy kod jest podobny do Ciebie i to nie daje przewijania. Ale patrz poniższy kod, w którym zmieniłem tylko StackPanel do Grid (dowolny panel który szanuje wielkość swoich dzieci na podstawie rozmiaru paneli ale StackPanel nie robi)

<Grid> 
    <ScrollViewer> 
     <ItemsControl > 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
     </ItemsControl> 
    </ScrollViewer> 
</Grid> 

UPDATE: Ale jeśli naprawdę trzeba użyć StackPanel wtedy może trzeba ustawić rozmiar dla ScrollViwer uzyskać zwój Content

+0

To może nie być możliwe, ponieważ wszystko jest wewnątrz StackPanel. Na stronie NIE ma siatki. Tylko master stackpanel, który zawiera dwa inne panele piętrowe. Dzieje się tak nawet wtedy, gdy mówię, że wysokość panelu sterującego ma wartość 100. – azamsharp

+0

Problem polega na tym, że każdy element sterujący w oknie jest zawarty w sterowaniu panelem sterującym. azamsharp

+2

Ale jeśli naprawdę trzeba używać StackPanel następnie może trzeba ustawić rozmiar dla ScrollViwer uzyskać zwój zawartość, bo jak powiedziałem wcześniej StackPanel robi respektować wysokość swoich dzieci lub szerokość. Musimy więc ustawić wysokość i szerokość, kiedy używamy StackPanel –

2

ItemsControl powinien zawierać ScrollViewer, a nie na odwrót. Wszystko, o czym wie ScrollViewer, to sama w sobie sprawa ItemsControl - nie wie o wewnętrznych elementach.

spróbować czegoś takiego:

<ItemsControl Name="icEvents" Width="Auto" Height="100" 
    Background="AliceBlue" 
    ItemsSource="{Binding Path=EventSources}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <StackPanel> 
       <TextBlock Text="Source:"/> 
       <TextBlock Text="{Binding Path=Source}" /> 
       <TextBlock Text="Original Source:"/> 
       <TextBlock Text="{Binding Path=OriginalSource}" /> 
      </StackPanel> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
    <ItemsControl.Template> 
     <ControlTemplate TargetType="ItemsControl"> 
      <ScrollViewer VerticalScrollBarVisibility="Auto"> 
       <ItemsPresenter Margin="5" /> 
      </ScrollViewer> 
     </ControlTemplate> 
    </ItemsControl.Template> 
</ItemsControl> 
+0

Nie jest konieczne, aby mieć scrollviwer, problem w pytaniu jest StackPanel. –

+1

Potrzebny jest jednak ScrollViewer, ponieważ domyślnie ItemsControl nie przewija. Użyłem tego kodu i działa, chociaż twoja odpowiedź prawdopodobnie też by działała. – Andy

+0

Tak, twój kod działa również tylko wtedy, gdy usuwa zewnętrzny StackPanel i nie ma znaczenia, że ​​pasek przewijania w ControlTemplate lub poza ItemsControl oba są prawie takie same. –

21

musisz naprawić wysokość ScrollViewer, ale można łatwo wiążą się StackPanel ActualHeight:
(kod testowane)

<StackPanel Name="mypanel"> 
    <ScrollViewer Height="{Binding ElementName=mypanel, Path=ActualHeight}"> 
     <ItemsControl> 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" /> 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" /> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" /> 
     </ItemsControl> 
    </ScrollViewer> 
</StackPanel> 

Albo jeszcze lepiej, jeśli nie można zmienić nazwę StackPanel:

<StackPanel> 
    <ScrollViewer Height="{Binding RelativeSource={RelativeSource FindAncestor, 
         AncestorType={x:Type StackPanel}}, Path=ActualHeight}"> 
     <ItemsControl> 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" /> 
      <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" Width="200"/> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" /> 
      <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" /> 
     </ItemsControl> 
    </ScrollViewer> 
</StackPanel> 

Jest to „najpierw” problemu, StackPanel zadawania ScrollViewer na wysokość i ScrollViewer zapytać StackPanel dla maksymalnej wysokości może być.

+2

Dziękuję za tak wyczerpującą odpowiedź! To na pewno się przyda! – azamsharp

+0

Niesamowita odpowiedź, zadziałała jak czar! – Jlange

0

Zwój musi być rodzicem zmieniającego dziecko, dlatego umieść w nim kontrolkę zmiany rozmiaru (w tym przypadku panel stosu).

<ScrollViewer> 
    <StackPanel> 
     <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/> 
     <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
     <Rectangle Stroke="#FFC3C3C3" Height="300" Fill="Black" StrokeThickness="4" Width="200"/> 
     <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
     <Rectangle Stroke="#FFC3C3C3" Width="200" Height="300" Fill="Black" StrokeThickness="4"/> 
    </StackPanel> 

0

miałem problem przy czym I wykazywały ItemsControl w sieci oraz, aby zobaczyć przewijania miałem, aby ten komórce siatki * -sized wysokości.

Jednak oznaczało to, że ItemsControl zawsze wypełniał komórkę, nawet jeśli było tylko kilka wartości.

Chciałem, aby ItemsControl był wystarczająco duży, aby pokazać, co miał, ale jeśli miał zbyt wiele przedmiotów, to chciałbym, żeby przewinął się. W kolejności słów chciałem, żeby to działało tylko na dowolny monitor wielkości.

Ten kod w załadowanym razie pracował dla mnie:

Size x = new Size(double.PositiveInfinity, double.PositiveInfinity); 
myItemscontrol.Measure(x); 
Powiązane problemy