0

I want my content inside my GridView to scroll when I start my storyboard. Right now the storyboard targets the gridview and not the content. How do I make it to scroll inside the gridview?

This is how my Storyboards and DataTemplates look like:

<Page.Resources    
 <Storyboard x:Key="CarouselStoryboard">
        <DoubleAnimation
            Storyboard.TargetName="CarouselTransform" 
            Storyboard.TargetProperty="X"/>
 </Storyboard>

    <DataTemplate x:Key="CatTemplate">
        <Grid>
            <StackPanel Margin="30,0,30,0" Background="Red">

        </StackPanel>
        </Grid>
    </DataTemplate>

  <DataTemplate x:Key="DogTemplate">
        <Grid>
            <StackPanel Margin="30,0,30,0" Background="Green">

        </StackPanel>
        </Grid>
    </DataTemplate>
</Page.Resources>

And this is how my Griview looks like:

<GridView x:Name="myGridView" ItemTemplateSelector="{StaticResource MyDataTemplateSelector}"
            ScrollViewer.HorizontalScrollBarVisibility="Hidden"
      ScrollViewer.HorizontalScrollMode="Auto"
      ScrollViewer.VerticalScrollBarVisibility="Disabled"
      ScrollViewer.VerticalScrollMode="Disabled">

        <GridView.RenderTransform>
            <TranslateTransform x:Name="CarouselTransform" />
        </GridView.RenderTransform>
        <GridView.ItemsPanel>
            <ItemsPanelTemplate>
                <ItemsWrapGrid Orientation="Vertical"/>
            </ItemsPanelTemplate>
        </GridView.ItemsPanel>

</GridView>
<Button Click="Left_Click" Content="Left" Background="Blue" HorizontalAlignment="Left"Width="405"/>

And this is how I start my storyboard using some C#

  private int currentElement = 0;

    private void Left_Click(object sender, RoutedEventArgs e)
    {
        if (currentElement < 100)
        {
            currentElement++;
            AnimateCarousel();
        }
    }
    private void AnimateCarousel()
    {
        Storyboard storyboard =  (this.Resources["CarouselStoryboard"] as Storyboard);
        DoubleAnimation animation = storyboard.Children.First() as DoubleAnimation;
        animation.To = -200 * currentElement;
        storyboard.Begin();
    }
LittleBird
  • 65
  • 9

1 Answers1

0

First of all, directly animate attach propery will not work due to we are lack of a reasonable built-in attached property:

  1. What is scrollview in control template:

It's typical for a ScrollViewer control to exist as a composite part of other controls. A ScrollViewer part, along with the ScrollContentPresenter class for support, will display a viewport along with scrollbars only when the host control's layout space is being constrained smaller than the expanded content size. This is often the case for lists, so ListView and GridView templates always include a ScrollViewer.

  1. To influence some of the behavior and properties that are from within the ScrollViewer part, ScrollViewer defines a number of XAML attached properties:

    • ScrollViewer.BringIntoViewOnFocusChange
    • ScrollViewer.HorizontalScrollBarVisibility
    • ScrollViewer.HorizontalScrollMode
    • ScrollViewer.IsDeferredScrollingEnabled
    • ScrollViewer.IsHorizontalRailEnabled
    • ScrollViewer.IsHorizontalScrollChainingEnabled
    • ScrollViewer.IsScrollInertiaEnabled
    • ScrollViewer.IsVerticalRailEnabled
    • ScrollViewer.IsVerticalScrollChainingEnabled
    • ScrollViewer.IsZoomChainingEnabled
    • ScrollViewer.IsZoomInertiaEnabled
    • ScrollViewer.VerticalScrollBarVisibility
    • ScrollViewer.VerticalScrollMode
    • ScrollViewer.ZoomMode
  2. Animating XAML attached properties:We can only animate built-in attached properties.

So instead of the above idea we need to get the ScrollView embeded in GridView first:

  1. Create your own GridView

    public class MyGridView:GridView
    {
     private ScrollViewer myscrollviewer;
    
     public ScrollViewer MyScrollViewer
     {
        get { return myscrollviewer; }
        set { myscrollviewer = value; }
     }
    
     protected override void OnApplyTemplate()
     {
        base.OnApplyTemplate();
        ScrollViewer testscrollviewer = GetTemplateChild("ScrollViewer") as ScrollViewer;
        myscrollviewer = testscrollviewer;
     }
    }
    
  2. Use it in your XAML:

    <local:MyGridView x:Name="mygv".../>
    
  3. Here since VerticalOffset is readonly, I cannot use DoubleAnimation to animate the scrollview. Thanks to Justin he has shared this workaround. With the help of ScrollView.ChangeView we can have some animation. And a more simple way if you don't need the animation:

     mygv.ScrollIntoView(mygv.Items[10], ScrollIntoViewAlignment.Leading);
    
LittleBird
  • 65
  • 9
Barry Wang
  • 1,459
  • 1
  • 8
  • 12
  • Thanks for detailed answer. But I can't get it to work. Nothing happens now when I click the button. I'm not sure how I can implement the code in my project – LittleBird Oct 29 '18 at 14:45
  • @LittleBird Any details about what you have done? Which way is chose by you to animate the scroll behavior? With or without animation? – Barry Wang Nov 02 '18 at 06:36