Register   |   Login

 

Spark Your Solution

 Scott's Technology Blog Minimize

Jun 11

Written by: Scott Davis
6/11/2008 8:55 PM

 
As part of a project I am working on, I wanted to be able to reuse a storyboard object to animate several controls the same way. At the end of the animation (the animation complete event) I needed to perform a final modification to the object. The problem with the animation object is that you can’t get back a reference to the object you animated. You can define which object to animate in two ways.  In the XAML tags, you set the name of the object (Storyboard.TargetName) on the animation object attributes. In the code behind, you use the Storyboard.SetTargetName([animation object],[string]) or Storyboard.SetTarget(([animation object],[target object]). When using the SetTarget you pass the object itself.
Unfortunately, there isn’t a getTarget method on the storyboard object in the codebehind, at least not as of Beta 2. So if you reuse a storyboard and animation on multiple objects, and need to do something to that target object at the end of the animation (the completion event), how do you get at that target object? The answer is to retrieve the target name, which is available, and use it to then go get the object from the page or user control, using this.FindName([string]).
The code below shows a custom user control that reuses a storyboard and animation to impact two controls, and modify them at the animation complete event. Clicking Button1 will cause the button’s opacity to change via the animation. Clicking Button2 will do the same thing, using the same animation. Notice the complete event which affects each button individually.
 
 
<UserControl x:Class="MyNamespace.StoryboardTest"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <StackPanel>
            <Button x:Name="Button1"
Content="Button1"
Click="Button1_Click"/>
            <Button x:Name="Button2"
Content="Button2"
Click="Button2_Click"/>           
        </StackPanel>
        <Grid.Resources>
<Storyboard x:Name="Storyboard1"
Completed="Storyboard1_Completed" >
                <DoubleAnimation x:Name="Animation1"
Duration="0:0:1"
Storyboard.TargetProperty="Opacity" />
            </Storyboard>
        </Grid.Resources>
    </Grid>
</UserControl>
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
 
namespace MyNamespace
{
    public partial class StoryboardTest : UserControl
    {
        public StoryboardTest()
        {
            InitializeComponent();
        }
 
        private void Storyboard1_Completed(object sender, EventArgs e)
        {
            //get the name of the control that was just animated
            string name = Storyboard.GetTargetName(Animation1);
            //go get the button - this code assumes a button was animated
            Button btnTarget = (Button)this.FindName(name);
            //did the button become near invisible
            //check is here just to show the animation completed
            if (btnTarget.Opacity < 0.3) 
            {
                //change the text on the button
                btnTarget.Content = "Near Invisible";
            }
        }
 
        private void Button1_Click(object sender, RoutedEventArgs e)
        {
            //XAML code already defines the target property as Opacity
            //This shows that mix of XAML and code behind works
            Storyboard.SetTargetName(Animation1, Button1.Name);
            Animation1.From = 1d;
            Animation1.To = .2d;
            Storyboard1.Begin();
        }
 
        private void Button2_Click(object sender, RoutedEventArgs e)
        {
            Storyboard.SetTargetName(Animation1, Button2.Name);
            Animation1.From = 1d;
            Animation1.To = 0.2d;
            Storyboard1.Begin();
        }
 
    }
}

Tags:

1 comments so far...

Re: How to reuse a Storyboard animation in Silverlight on multiple target controls

This doesn't work when you use SetTarget in the code instead of SetTargetName. In that case you get null. There needs to be a GetTarget method of this whole framework is useless. FindName breaks down using different namescopes.

By razor247 on   7/12/2009 3:57 PM

Your name:
Title:
Comment:
Add Comment    Cancel  

  
 Blog Dates Minimize

 Print   
 Search Minimize

 Print