locked
How to apply two storyboard animations to a grid which is present in a datatemplate of listview.

    Question

  • Hi All,

    I have a code as shown below. Now i want to apply the storyboard animations  to grids 1 and 2 like

    1.Whenever grid is loaded storyboard "abc" has to start(that I implemented using routedevents =Grid.Loaded)

    2.whenever storyboard abc has completed storyboard "def" has to start.

    3. after that storyboard "abc" has to start and repeat it for ever.

    Could anyone please help me to figure out this problem?

    <ListView Name="list1">
        <ListView.ItemTemplate>
            <DataTemplate>
    
    	<stack panel>
    
    	    <grid1></grid1>
    
    	    <grid2>
        
                 <Grid.Triggers>
                      <EventTrigger x:Name="evttrigger1" RoutedEvent="Grid.Loaded" >
                            <BeginStoryboard>
                                 <Storyboard x:Name="abc" completed="one_completed">
                                                
                                 </Storyboard>
                             </BeginStoryboard>
                        </EventTrigger>
                        <EventTrigger x:Name="evttrigger2" RoutedEvent="one_completed" >
                            <BeginStoryboard>
                                 <Storyboard x:Name="def" completed="two_completed">
                                                
                              </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
    
                                </Grid.Triggers>
                            </Grid>                        
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>     
    
    	    </grid2>



    Thursday, August 07, 2014 10:53 AM

Answers

  • Below is how you would create the first Storyboard programmatically. Note that target is a reference to the element you call "panel1" in your XAML. You need to find this element in the visual tree using the FindVisualChild method (change the type from Button to the type of "panel1").

    DependencyObject target = FindVisualChild<Button>(grid); //target = "panel1"
                //liveTileAnim1:
                DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
                Storyboard.SetTarget(animation, target);
                Storyboard.SetTargetProperty(animation, "Y");
                animation.BeginTime = TimeSpan.FromSeconds(1);
    
                //create all SplineDoubleKeyFrames:
                SplineDoubleKeyFrame frameA = new SplineDoubleKeyFrame();
                frameA.Value = 0;
                frameA.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(100));
                animation.KeyFrames.Add(frameA);
    
                SplineDoubleKeyFrame frameB = new SplineDoubleKeyFrame();
                frameB.Value = -40;
                frameB.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(400));
                animation.KeyFrames.Add(frameB);
    
                //and so on...
    
                Storyboard storyBoard = new Storyboard();
                storyBoard.Children.Add(animation);
                storyBoard.Begin();
    

    • Marked as answer by Badri Bharath Thursday, August 14, 2014 6:36 AM
    Wednesday, August 13, 2014 7:24 AM

All replies

  • Whenever you need to perform some fairly more advanced logic in connection to animations, you should create the animations programmatically. If you handle the Loaded event of the Grid in the ItemTemplate of the ListView, you could create the Storyboards programmatically and hook up event handlers for their Completed event:

         <ListView Name="list1">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <Grid Loaded="Grid_Loaded">
                            <Button x:Name="button" Background="Yellow" Content="Button..." Width="500" Height="100" Opacity="0"/>
                        </Grid>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

    private void Grid_Loaded(object sender, RoutedEventArgs e)
            {
                Grid grid = sender as Grid;
    
                //create ABC Storyboard
                CreateAbcStoryboard(grid);
            }
    
    
            private void CreateAbcStoryboard(Grid grid)
            {
                Button button = FindVisualChild<Button>(grid);
    
                //create ABC Storyboard
                DoubleAnimation animation = new DoubleAnimation();
                animation.Duration = TimeSpan.FromSeconds(1);
                animation.From = 0;
                animation.To = 1;
                Storyboard.SetTarget(animation, button);
                Storyboard.SetTargetProperty(animation, "Opacity");
    
                Storyboard abc = new Storyboard();
                abc.Completed += (s, g) => abc_Completed(button, grid);
                abc.Children.Add(animation);
                abc.Begin();
            }
    
            void abc_Completed(Button button, Grid grid)
            {
                //create DEF Storyboard
                DoubleAnimation animation = new DoubleAnimation();
                animation.EnableDependentAnimation = true;
                animation.Duration = TimeSpan.FromSeconds(1);
                animation.From = 500;
                animation.To = 200;
                Storyboard.SetTarget(animation, button);
                Storyboard.SetTargetProperty(animation, "FrameworkElement.Width");
    
                Storyboard def = new Storyboard();
                def.Completed += (s, g) => CreateAbcStoryboard(grid);
    
                def.Children.Add(animation);
                def.Begin();
            }
    
            private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
            {
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
                {
                    DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                    if (child != null && child is T)
                        return (T)child;
                    else
                    {
                        T childOfChild = FindVisualChild<T>(child);
                        if (childOfChild != null)
                            return childOfChild;
                    }
                }
                return null;
            }
    

    The above sample code animates the Opacity property of a Button (from 0 to 1) inside the ItemTemplate before it animates the Width property of the same Button (from 200 to 500). Once the second animation has completed, the first one starts again and when it is completed the second one starts again and so on.

    Thursday, August 07, 2014 3:03 PM
  • Thanks Magnus for spending your time to solve the problem but, As I am new to Xaml I am unable to figure out how to achieve the following storyboard Programmatically . Could you please help me to figure out this?

    <Storyboard x:Name="liveTileAnim1" Duration="0:0:10" Completed="liveTileAnim1_Completed">
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:01"  Storyboard.TargetName="panel1" Storyboard.TargetProperty="Y">
                    <SplineDoubleKeyFrame KeyTime="00:00:00.100" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.200" Value="-40"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="-60"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.400" Value="-75"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.500" Value="-84"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.700" Value="-91"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.900" Value="-96"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:01.100" Value="-98"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:01.400" Value="-99"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:01.700" Value="-100"/>
                </DoubleAnimationUsingKeyFrames>
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:01"  Storyboard.TargetName="panel2" Storyboard.TargetProperty="Y">
                    <SplineDoubleKeyFrame KeyTime="00:00:00.100" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.200" Value="-40"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.300" Value="-60"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.400" Value="-75"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.500" Value="-84"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.700" Value="-91"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:00.900" Value="-96"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:01.100" Value="-98"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:01.400" Value="-99"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:01.700" Value="-100"/>
                </DoubleAnimationUsingKeyFrames>            
            </Storyboard>

    Wednesday, August 13, 2014 5:14 AM
  • Below is how you would create the first Storyboard programmatically. Note that target is a reference to the element you call "panel1" in your XAML. You need to find this element in the visual tree using the FindVisualChild method (change the type from Button to the type of "panel1").

    DependencyObject target = FindVisualChild<Button>(grid); //target = "panel1"
                //liveTileAnim1:
                DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
                Storyboard.SetTarget(animation, target);
                Storyboard.SetTargetProperty(animation, "Y");
                animation.BeginTime = TimeSpan.FromSeconds(1);
    
                //create all SplineDoubleKeyFrames:
                SplineDoubleKeyFrame frameA = new SplineDoubleKeyFrame();
                frameA.Value = 0;
                frameA.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(100));
                animation.KeyFrames.Add(frameA);
    
                SplineDoubleKeyFrame frameB = new SplineDoubleKeyFrame();
                frameB.Value = -40;
                frameB.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(400));
                animation.KeyFrames.Add(frameB);
    
                //and so on...
    
                Storyboard storyBoard = new Storyboard();
                storyBoard.Children.Add(animation);
                storyBoard.Begin();
    

    • Marked as answer by Badri Bharath Thursday, August 14, 2014 6:36 AM
    Wednesday, August 13, 2014 7:24 AM