Categories: Blog

Initializing the FROM value of a Silverlight 2 Animation

Recently, I was attempting to create my own popup dialog. I had specific requirements in mind for this dialog, including: 

  1. I wanted to animate the Width/Height from 0x0 to the ActualWidth/ActualHeight
  2. I wanted to animate the Opacity from 0 to 1
  3. I wanted to animate the Top/Left properties from the point of mouse click (an icon in my case) to the center of the screen and back to the original point of mouse click when the user closed the dialog

All of these are fairly easy to accomplish using a Storyboard with an x:Name specified.  In the case of my requirement #3 above, I merely needed to set the From value of my animation and call the Begin() method, like so (for purposes of illustration, I’ll confine this to the Canvas.Left property only…you can apply the same logic to the Canvas.Top property and it’s all in the accompanying project):

<Storyboard x_Name="MoveDialogStoryboard">
  <DoubleAnimation
       x_Name="theDialogAnimation"
       Storyboard.TargetName="theDialog" 
       Storyboard.TargetProperty="(Canvas.Left)"
      To="0" Duration="0:0:0.5" />
  </Storyboard>

theDialogAnimation.From = 800;   // this value would actually come from getting the mouse position via GetPosition()
(MoveDialogStoryboard as Storyboard).Begin();

This all works as you would expect.  However, I really liked the idea of isolating all of my dialog states into one place and
the Visual State Manager sounded like the perfect solution…that is, until I tried to set the FROM value programmatically and got hit with a NullReferenceException every time I tried to reference my named Animation. 

I tried several things and ended up posting my issue to the Silverlight forum where Shawn Wildermuth was kind enough to offer a solution.  Shawn’s solution was to simply set the property to the value before calling GoToState() in my code.  This made perfect sense and I ran off to give it a try.  It worked…once.  My animation would fire once but then appear to be swallowed or ignored on subsequent clicks.  After further investigation, this turned out to be an artifact of the fact that I was never setting my VisualState back to the original state…something you don’t have to do when using a Storyboard outside of the Visual State Manager.  So, that fixed that issue and Shawn’s solution worked.  However, I didn’t really see any way using this solution to animate back to the original point of mouse click.   

Either way, it didn’t really satisfy my initial curiosity for WHY I couldn’t programmatically set the FROM value when my animation was inside a Visual State Manager, so I pressed on.  Thanks to a couple of blog posts (here and here) and some pretty ugly LINQ, I was finally able to programmatically set the FROM value and have it animate my dialog from the original point of mouse click with a Storyboard inside of a VisualState like so: 

public void ShowDialog(Point startingPosition)
{
     Storyboard storyboard = Utils.FindStoryboard(LayoutRoot, "DialogStates", "Open");
     (storyboard.Children[0] as DoubleAnimation).From = startingPosition.X;
     (storyboard.Children[1] as DoubleAnimation).From = startingPosition.Y;
     VisualStateManager.GoToState(this, "Open", true);
}

// This is the definition of the extension method FindStoryboard() shown above (which is where the real work happens)
public static Storyboard FindStoryboard(this FrameworkElement parent, string groupName, string stateName)
{
     VisualState visualState = VisualStateManager.GetVisualStateGroups(parent)
         .Cast<VisualStateGroup>().Where(group => group.Name == groupName)
         .SingleOrDefault()
         .States.Cast<VisualState>()
         .Where(state => state.Name == stateName)
         .SingleOrDefault();

     if (visualState != null)
         return visualState.Storyboard;    

     return null;    
}

All of that being said, I didn’t end up going this route nor do I recommend it.  It’s way too brittle and just plain ugly in my opinion.  In the end, I chose to create my Open and Closed Storyboard animations for my popup dialog as standard Resource Storyboar

ds where I don’t have to reset the State before calling and I don’t have to jump through hoops to set the value and, most importantly, I can set a name for the Animation and directly set the property value.  For the actual "modes" of my dialog (assuming there are multiple views for the dialog), I used the VSM to represent things like EntryView, EditView, etc.  I think this offers a much cleaner solution.

I’ve put together a quick demo to illustrate both calling the Storyboard directly and using a Storyboard in a VSM.  The live version is here and the project source is available here

Rik Robinson

Recent Posts

8-Step AWS to Microsoft Azure Migration Strategy

Microsoft Azure and Amazon Web Services (AWS) are two of the most popular cloud platforms.…

2 weeks ago

How to Navigate Azure Governance

 Cloud management is difficult to do manually, especially if you work with multiple cloud…

3 weeks ago

Why Azure’s Scalability is Your Key to Business Growth & Efficiency

Azure’s scalable infrastructure is often cited as one of the primary reasons why it's the…

1 month ago

Unlocking the Power of AI in your Software Development Life Cycle (SDLC)

https://www.youtube.com/watch?v=wDzCN0d8SeA Watch our "Unlocking the Power of AI in your Software Development Life Cycle (SDLC)"…

2 months ago

The Role of FinOps in Accelerating Business Innovation

FinOps is a strategic approach to managing cloud costs. It combines financial management best practices…

2 months ago

Azure Kubernetes Security Best Practices

Using Kubernetes with Azure combines the power of Kubernetes container orchestration and the cloud capabilities…

2 months ago