Archive

Posts Tagged ‘animation’

Animating the Visibility property

August 30th, 2009 Pedro Pombeiro 2 comments

This post is sort of a future reference for myself. I needed to animate the Visibility property as part of a larger Storyboard, and it wasn’t immediately apparent how to do it. It took a bit of effort to find the solution on Google, so I am posting the solution in hope that it will make someone else’s life easier as well.

If you have something like the following, for an object that is usually hidden:

<Setter Property="Visibility" Value="Visible" />

and you want to fade in the object instead of suddenly showing it, you will need to convert the Setter into an Animation action in a Storyboard. You are probably aware of the DoubleAnimation and BooleanAnimationUsingKeyFrames classes already. To animate the Visibility property, however – which is an enum –, the solution is not immediately apparent: you need to use ObjectAnimationUsingKeyFrames:

<Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
        <DiscreteObjectKeyFrame KeyTime="00:00:00">
            <DiscreteObjectKeyFrame.Value>
                <Visibility>Visible</Visibility>
            </DiscreteObjectKeyFrame.Value>
        </DiscreteObjectKeyFrame>
    </ObjectAnimationUsingKeyFrames>

    <DoubleAnimation Duration="00:00:01" Storyboard.TargetProperty="Opacity" To="1" />
</Storyboard>

There you go. The animation will start by making the object visible, and then animating it to 100% opaque. Hope this helps you!

Shout it

kick it on DotNetKicks.com

Share and Enjoy:
  • Digg
  • del.icio.us
  • DotNetKicks
  • DZone
  • Technorati
  • LinkedIn
  • Google Bookmarks
  • StumbleUpon
  • email
  • Print
Categories: Tips Tags: ,

Animating a data-bound color property

August 17th, 2009 Pedro Pombeiro No comments

As I was going through the UI of the Scrum Sprint Monitor to introduce animations to the larger UI elements, one type of property was proving difficult to animate: the dynamic background color of some elements which were bound to Brush (or Color) properties of the ViewModel.

Picture this: you have a Color property that is currently Green. At some point it changes to Red. You would like the UI to update smothly, so you would not see the color jump from Green to Red. You are not able to do this in XAML with triggers and storyboards directly. The problem lies in the fact is that the Animation objects in XAML cannot be bound to dynamic values (see instances here and here), as they must be frozen for performance and thread safety reasons.

<DataTemplate DataType="{x:Type ViewModels:BuildStatusBackgroundViewModel}">
    <Grid Background="{Binding Path=BuildStatusColor}" />
</DataTemplate>

Therefore there is no point in trying to introduce triggers (be it EventTriggers or DataTriggers) in this Grid element. What I ended up doing is deriving a class from Grid and spawning the animation from code behind.

<DataTemplate DataType="{x:Type ViewModels:BuildStatusBackgroundViewModel}">
    <Controls:BuildStatusBorder />
</DataTemplate>

See the code-behind example here. I did encounter a pitfall while developing this approach. I ran into a “Cannot freeze this Storyboard timeline tree for use across threads” exception, when the animation was kicked off. I fixed this by cloning the existing property value, essentially removing any data binding from the property.

Hope this helps someone who is running into the same problem of animating transitions between databound properties!

Shout it

Share and Enjoy:
  • Digg
  • del.icio.us
  • DotNetKicks
  • DZone
  • Technorati
  • LinkedIn
  • Google Bookmarks
  • StumbleUpon
  • email
  • Print

Animated WPF Panels (animating collection views)

August 14th, 2009 Pedro Pombeiro No comments

UPDATE: The same functionality is now available out of the box using the Blend 3 SDK, through the FluidMoveBehavior. Just drag that behavior to your container panel, and set the Duration and AppliesTo properties! The only difference is that easing functions are not yet supported in WPF. We will need to wait until WPF 4 is released.

Last evening I finally implemented a long awaited feature (by me!) in the Scrum Sprint Monitor: animated WPF panels. As the team members in the Sprint move up and down the list (an ObservableCollection<>), get added or removed, I always wished that change could be animated. My current knowledge of the WPF layout mechanism wasn’t sufficient to finish on that endeavor within a few hours, though.

I finally found a blog post that set me on the right path, on Ed Foh’s blog. Ed in turn was inspired by Kevin Moore’s WPF Bag of Tricks, which also includes an Animating Tile Panel.

Here is a video demonstrating the enhanced behavior of my AnimatedUniformGrid:

An AnimatedUniformGrid in action

Why those two solutions didn’t work for me

Both of the aforementioned solutions contained hardwired positioning logic, though. I simply needed to add the animation behavior to StackPanel, WrapPanel and UniformGrid, not a completely custom panel. Ideally, the solution would be a behavior that could be added on top of those containers. That particular aspect wasn’t realized, and I ended up deriving classes for each of these panels, prefixing the new classes with “Animated”. It is still a pretty acceptable solution. UPDATE: I eventually found this was the same approach taken by at least one commercial offer.

The following is the code required to instantiate the uniform grid (note how you simple need to prefix the panel class with Wpf:Animated):

<ItemsControl ItemsSource="{Binding TeamMembersIncludingUnassigned}">
    <ItemsControl.ItemsPanel>
      <ItemsPanelTemplate>
         <Wpf:AnimatedUniformGrid Duration="00:00:01" />
      </ItemsPanelTemplate>
   </ItemsControl.ItemsPanel>
</ItemsControl>

 

Adding animation to an existing panel control class

The workflow for converting an existing Panel to an AnimatedPanel is pretty easy:

  1. derive a new class from the desired panel class (prefix it with Animated);
  2. override the ArrangeOverride method in the new class (don’t call the base class implementation);
  3. using .NET Reflector, extract the ArrangeOverride method contents from the base class implementation, and simply substitute the element.Arrange call that is performed for each child for a call to the AnimatedPanelHelper.ArrangeChild() static method.

That is all you need to do!

Acknowledgements

Thanks to Ed Foh and Kevin Moore for their great work.

Download the source code here.

Shout it
 
kick it on DotNetKicks.com
Share and Enjoy:
  • Digg
  • del.icio.us
  • DotNetKicks
  • DZone
  • Technorati
  • LinkedIn
  • Google Bookmarks
  • StumbleUpon
  • email
  • Print