ScrollViewer ne défile pas dans WPF

J'utilise un contrôle scrollviewer autour de mon panneau de pile qui contient un ItemsControl. Quand il y a beaucoup d'éléments dans le ItemsControl, il est supposé faire défiler mais pour une raison quelconque, il ne fait que couper les éléments. Voici le code:

<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>
28
demandé sur NSGaga 2009-07-15 22:04:36

5 réponses

Essayer une grille autour de votre ScrollViwer au lieu de StackPanel. Je pense que StackPanel fournira autant de hauteur que le contenu interne le souhaite, donc ici le Scrollviwer ne fonctionne pas correctement puisque sa hauteur n'est pas restreinte par son contrôle parent.

, Vous pouvez comprendre le problème à partir de l'exemple ci-dessous.

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

Le code ci-dessus est similaire au vôtre et ne vous donne pas de barres de défilement. Mais voir le code ci-dessous dans lequel j'ai changé seulement le StackPanel à un Grid (tout panneau qui respecte la taille de son enfants basés sur la taille des panneaux mais pas stackpanel)

<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 : Mais si vous avez vraiment besoin d'utiliser StackPanel, vous devrez peut-être définir la taille de votre ScrollViwer pour obtenir le défilement de contenu

42
répondu Jobi Joy 2016-02-12 10:49:55

Vous devez fixer la hauteur du Scrollviewer, mais peut facilement se lier au StackPanel ActualHeight:
(code testé)

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

Ou mieux encore, si vous ne pouvez pas changer le nom du 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>

C'est un problème" vous d'abord", le StackPanel demande au ScrollViewer la hauteur et le ScrollViewer demande au StackPanel la hauteur maximale qu'il peut être.

22
répondu Eduardo Molteni 2009-07-15 19:00:22

Le ItemsControl doit contenir les ScrollViewer, pas l'inverse. Tout ce que le ScrollViewer connaît est le ItemsControl lui-même dans votre cas-il ne connaît pas les éléments intérieurs.

Essayez quelque chose comme ceci:

<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>
2
répondu Andy 2009-07-15 18:10:08

Le défilement doit être le parent de l'enfant de redimensionnement, alors placez le contrôle de redimensionnement(dans ce cas, le panneau de pile) à l'intérieur.

<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
répondu MikeT 2012-03-19 17:37:39

J'ai eu un problème par lequel j'ai montré un ItemsControl dans une grille et pour voir les barres de défilement, j'ai dû donner à cette cellule de grille une hauteur de taille*.

Cependant, cela signifiait que le ItemsControl remplissait toujours la cellule même s'il n'y avait que quelques valeurs.

Je voulais que le ItemsControl soit seulement assez grand pour montrer ce qu'il avait mais s'il avait trop d'éléments, je voulais qu'il défile. Dans les mots d'ordre, je voulais que cela ne fonctionne que n'importe quel moniteur de taille.

Ce code dans L'événement chargé a fonctionné pour moi:

Size x = new Size(double.PositiveInfinity, double.PositiveInfinity);
myItemscontrol.Measure(x);
0
répondu Richard Fencel 2014-04-27 19:08:36