Swapping Content In the Code Behind in Silverlight

I fought with this for a while today, so I thought I would toss it up as a solution.

I was trying to create a transition between two screens for a project I’m working on. I created the two ContentControls in my XAML like so:

<ContentControl x:Name=”OldContent”>
     
<!– My Old Content –>
</ContentControl>
<
ContentControl x:Name=”NewContent” Opacity=”0″>
     
<!– My New Content –>
</ContentControl>

Let’s say for the sake of this post that I was trying to animate the top content as a fade in and then, after the animation is done,  put the top content into the bottom content so that I could fill the NewContent with something else and have it ready for the next transition.

So… I’m using the following animation.

<Storyboard x:Name=”TransitionContent”>
   <
DoubleAnimationUsingKeyFrames BeginTime=”00:00:00″
         Storyboard.TargetName=”NewContent”
         Storyboard.TargetProperty=”Opacity”>
                <
SplineDoubleKeyFrame KeyTime=”00:00:00.03″ Value=”1″ />
   </DoubleAnimationUsingKeyFrames>
</
Storyboard>

(No Blend stuff today because I’m going a mile a minute for the sake of my looming project deadline.)

I add a “Completed” event handler to my Storyboard so that I can swap the content when the animation is over.

<Storyboard x:Name=”TransitionContent” Completed=”TransitionContent_Completed”>

In the C# code behind, I first wrote my content swapping like this:

this.OldContent.Content = this.NewContent.Content;
this.NewContent.Content = null;

And I got the following exception:

“System.ArgumentException was unhandled by user code
      Value does not fall within the expected range.”

I’m putting this in because it took me quite some time to figure out what the problem was. Simply put… Silverlight was yelling at me because I was trying to put the same stuff in the visual tree twice. This would have meant two copies of anything with a x:Name attribute… which would have been made it really hard for me to find anything. So it threw an exception.

Ultimately, I had to create an object to store the value of the NewContent  and then trash the NewContent.Content before I could put it into the OldContent.Content. I’ve re-written the code in such a way that if you wanted to swap the two contents, it will do just that.

private void Storyboard2_Completed(object sender, EventArgs e)       
{
            object oldStuff = this.OldContent.Content as object;
            object newStuff = this.NewContent.Content as object;

            this.OldContent.Content = null;
            this.NewContent.Content = null;

            this.OldContent.Content = newStuff;
            this.NewContent.Content = oldStuff;

            this.NewContent.Opacity = 0;
}

That last little bit is to reset the NewContent so that it is ready for the next transition.

And that’s all there is to it.