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>
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
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.
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>
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>
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);