Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollViewer not scrolling in WPF

I am using a scrollviewer control around my stack panel which contains an ItemsControl. When there are many items in the ItemsControl it is suppose to scroll but for some reason it just cuts of the items. Here is the 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>
like image 834
azamsharp Avatar asked Jul 15 '09 18:07

azamsharp


3 Answers

Try a grid around your ScrollViwer instead of the StackPanel. I think StackPanel will provide as much height as the internal content wants, so here the Scrollviwer doesn't work properly since its height is not get restricted by its parent control.

You can understand the issue from the example below.

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

Above code is similar to yours and it doesn't give you scrollbars. But see the below code in which I changed only the StackPanel to a Grid(Any panel which respects the size of its children based on panels size but stackpanel doesn't)

<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 : But if you really need to use StackPanel then you might need to set the size for your ScrollViwer to get the Content scroll

like image 188
Jobi Joy Avatar answered Sep 22 '22 05:09

Jobi Joy


You must fix the Height of the Scrollviewer, but can easily bind to the StackPanel ActualHeight:
(tested code)

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

Or better yet, if you can't change the name of the 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> 

It is a "You first" problem, the StackPanel ask the ScrollViewer for the Height and the ScrollViewer ask the StackPanel for the max Height it can be.

like image 22
Eduardo Molteni Avatar answered Sep 22 '22 05:09

Eduardo Molteni


The ItemsControl should contain the ScrollViewer, not the other way around. All that the ScrollViewer knows about is the ItemsControl itself in your case - it doesn't know about the inner items.

Try something like this:

<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>
like image 29
Andy Avatar answered Sep 21 '22 05:09

Andy