Search code examples
c#wpfxamlscrollviewstackpanel

StackPanel inside of a ScrollView doesnt physically scroll correctly


Consider the following XAML (a UserControl):

<Grid x:Name="LayoutRoot" ScrollViewer.VerticalScrollBarVisibility="Disabled">
    <Grid HorizontalAlignment="Right" Width="335.312" ScrollViewer.VerticalScrollBarVisibility="Disabled">
        <ed:BlockArrow Fill="#FFF4F4F5" HorizontalAlignment="Left" Margin="0" Orientation="Left" Stroke="Black" Width="15" RenderTransformOrigin="5.6,-0.412" Height="12" VerticalAlignment="Center" MouseEnter="LeftArrow_MouseEnter" MouseLeave="LeftArrow_MouseLeave" MouseLeftButtonUp="LeftArrow_MouseLeftButtonUp"/>
        <ed:BlockArrow Fill="#FFF4F4F5" Stroke="Black" RenderTransformOrigin="5.6,-0.412" Height="12" VerticalAlignment="Center" MouseEnter="RightArrow_MouseEnter" MouseLeave="RightArrow_MouseLeave" HorizontalAlignment="Right" Width="15" MouseLeftButtonUp="RightArrow_MouseLeftButtonUp"/>
        <ScrollViewer x:Name="panelScrollViewer" Margin="15,0" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden">
            <StackPanel x:Name="slidingStackPanel" Orientation="Horizontal" Height="125.882" Width="305.312" ScrollViewer.VerticalScrollBarVisibility="Disabled" CanHorizontallyScroll="True" ScrollViewer.CanContentScroll="False"/>
        </ScrollViewer>
    </Grid>
</Grid>

I am looking to physically scroll this stackpanel. I dynamically add elements to the stackpanel, and this appears to work correctly. In another button's click function, the following code is executed:

panelScrollViewer.ScrollToHorizontalOffset(100);

The scrollview and the stackpanel's HorizonalOffset is still zero! Also, the stackpanel's ScrollOwner is null. Any ideas?


Solution

  • Since you do not specify a width of the ScrollViewer, it takes the size of the StackPanel. Because the content of the ScrollViewer is not larger than its size then it will not scroll and will always have a horizontal offset of 0. Try setting the width of the ScrollViewer to something smaller than its contents and you should have a working horizontal scroll.

    Also remove all the redundancy of disabling the vertical scroll bars, once is good enough.

    <Grid x:Name="LayoutRoot">
    <Grid HorizontalAlignment="Right" Width="335.312">
        <ed:BlockArrow Fill="#FFF4F4F5" HorizontalAlignment="Left" Margin="0" 
             Orientation="Left" Stroke="Black" Width="15" RenderTransformOrigin="5.6,-0.412"
             Height="12" VerticalAlignment="Center" MouseEnter="LeftArrow_MouseEnter" 
             MouseLeave="LeftArrow_MouseLeave" MouseLeftButtonUp="LeftArrow_MouseLeftButtonUp"/>
        <ed:BlockArrow Fill="#FFF4F4F5" Stroke="Black" RenderTransformOrigin="5.6,-0.412" 
             Height="12" VerticalAlignment="Center" MouseEnter="RightArrow_MouseEnter" 
             MouseLeave="RightArrow_MouseLeave" HorizontalAlignment="Right" Width="15" 
             MouseLeftButtonUp="RightArrow_MouseLeftButtonUp"/>
        <ScrollViewer x:Name="panelScrollViewer" Margin="15,0" CanContentScroll="False" 
              VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Hidden"
              Width="250">
            <StackPanel x:Name="slidingStackPanel" Orientation="Horizontal" Height="125.882" Width="305.312"/>
        </ScrollViewer>
    </Grid>