One natural way to create some visual effects would seem to be animating the clipping path of a visual element. Sitting down in either Visual Studio or Blend 3 will immediately show there’s not a straightforward way to do this. There have been some other means of doing this posted online involving creating a Storyboard and DoubleAnimation entirely in a code-behind. Since one of our goals when using Silverlight and Blend should be a clean designer/developer separation, I didn’t care for this approach.
We’re going to build a “wipe” effect using animation and clipping paths and the only code behind will be the Storyboard trigger.
Setup
I’m first going to create a Silverlight 3 Navigation application and throw in my own styles. I add a Page called AnimateClip.xaml and throw in a DataGrid containing some sample wine data and a button I can push to test the “wipe” effect. The application looks like this when I navigate to the new page:
DataGrid XAML
I’m going to apply the Wipe effect to the DataGrid. Here’s the initial XAML defining my grid. As you’ve already seen above I created some Sample Wine data to populate the DataGrid.
<data:DataGrid x:Name="WineGrid" AutoGenerateColumns="True" IsReadOnly="True" CanUserResizeColumns="True" Grid.Row="1" Width="500" Height="200" RenderTransformOrigin="0,.5">
<data:DataGrid.Clip>
<RectangleGeometry Rect="0,0,500,200">
<RectangleGeometry.Transform>
<ScaleTransform x:Name="WipeScale" ScaleX="1" ScaleY="1"/>
</RectangleGeometry.Transform>
</RectangleGeometry>
</data:DataGrid.Clip>
</data:DataGrid>
Note that I’ve given the DataGrid a clipping geometry that exactly matches the bounds the DataGrid has anyway. The RectangleGeometry gets its dimensions from a Rect property. The struct Rect has a Width property, but Rect.Width does not appear to be backed by a DependecyProperty, so we can’t simply animate the Width of a Rect. Without creating new Rect structs and manually animating in C#, some trial and error was needed in order to find a workable XAML-only solution. The solution is to name the ScaleTransform and animate its Properties.
I’m going to create the Storyboard manually in XAML, we’ll see why when moving to Blend 3 in a minute.
<Storyboard x:Name="WipeGrid">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="WipeScale"
Storyboard.TargetProperty="ScaleX">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
So, this is fairly simple once we figure out how to effectively animate the bounds of the DataGrid. Ordinarily this Storyboard would produce a uniform “shrink in” effect. The default RenderTransformOrigin is of course the very center of a UIElement. Because the RenderTransformOrigin of the DataGrid is set to 0, .5 we get the desired “wipe” effect as we are calculating from the left side rather than the center.
When I press the Wipe Out button the code-behind starts the Storyboard. The wipe effect now works as desired.
Polish
As I enjoyed how the wipe effect looked, I thought perhaps I’d use some of the new built in easing functions to make it even better. In the recently released Expression Blend 3 + SketchFlow, this is what I see when attempting to edit my Storyboard:
Despite the fact that the Storyboard works, the clipping path is missing something needed for Blend to be able to show it for timeline editing. I assume this is because it’s technically not a visual element in the tree, but just a humble RectangleGeometry used to modify a visual element. I really don’t feel like learning the ins and outs of all of the easing functions and their parameters, so for now I had to create a bogus storyboard and copy it to this Page. The Quadratic Ease (InOut) produced the effect I was going for.
<Storyboard x:Name="WipeGrid">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="WipeScale"
Storyboard.TargetProperty="ScaleX">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<QuarticEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<QuarticEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
So, while that would not be bad as far as hand-crafting XAML it would be better if I didn’t have to build fake Storyboards to create my visual effects. With a more complex Storyboard mistakes might be made in the manual copy & conversion process. You now have an alternate way to animate clipping paths in Silverlight using XAML.