Using a Single Storyboard on Multiple Elements
On a secret little project I've been working on for the last two
weeks I came across something interesting in Silverlight and WPF.
When
you're developing WPF applications, code and XAML re-use is paramount.
Using templates is an absolute requirement to reduce the amount of XAML
that a client has to download especially for Silverlight. So this
raises an interesting point. Can we have a single storyboard that can
be applied to many elements without much hassle.
So here we go!
In our Silverlight application we have the XAML as below. We have a
canvas with two textblocks and a storyboard that moves a target's left
property from 0 to 100. You may notice that no TargetName is being set
on the storyboard. This is because we want to set this dynamically.
<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Canvas.Resources>
<Storyboard x:Name="MoveAround" Completed="MoveDone">
<DoubleAnimation Storyboard.TargetProperty="(TextBlock.Left)" From="0" To="100" Duration="0:1:0" />
</Storyboard>
</Canvas.Resources>
<TextBlock x:Name="Text" Height="20" Width="20" Canvas.Left="0" Canvas.Top="10" MouseLeftButtonUp="MoveAround" />
<TextBlock x:Name="Text" Height="20" Width="20" Canvas.Left="0" Canvas.Top="50" MouseLeftButtonUp="MoveAround" />
</Canvas>
We have also set the MouseLeftButtonUp event to run a function called MoveAround. This function looks like this:
<script type="text/javascript">
function MoveAround(sender, args)
{
var senderName = sender.Name.toString();
sender.findName("MoveAround")["Storyboard.TargetName"]=senderName;
sender.findName("MoveAround").Begin();
}
function MoveDone(sender, args)
{
sender.findName("MoveAround").stop();
}
</script>
What
this does is apply the storyboard to the sender (the element that
called the function) and start the storyboard. We also have the
MoveDone function to stop the animation after we're done with the
animation as Silverlight will throw an exception if we don't.
So in a very short time we can implement a single storyboard that can be applied to many elements. Pretty sweet!