views:

1681

answers:

2

I am trying to adapt a simple WPF application to use the Model-View-ViewModel pattern. On my page I have a couple of animations:

<Page.Resources>
    <Storyboard x:Name="storyboardRight" x:Key="storyboardRight">
        <DoubleAnimation x:Name="da3" Storyboard.TargetName="labelRight" Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.5" />
        <DoubleAnimation x:Name="da4" Storyboard.TargetName="labelRight" Storyboard.TargetProperty="Opacity" From="1" To="0" BeginTime="0:0:1" Duration="0:0:0.5" />
    </Storyboard>
    ...
</Page.Resources>

Currently I begin the animation in the code behind, and can listen to the Completed event to do something when it finishes with the following code:

storyboardRight = (Storyboard)TryFindResource("storyboardRight");
storyboardRight.Completed += new EventHandler(storyboardRight_Completed);
storyboardRight.Begin(this);

Is there a way of data binding the storyboard to my ViewModel so that it starts on an event raised by the ViewModel and can call-back into that ViewModel when it is finished?

+1  A: 

You need to use an EventTrigger. This article about Animations in WPF might help. See also the Routed Events Overview on the MSDN and How to: Use Event Triggers to Control a Storyboard After It Starts.

David Schmitt
thanks for the pointer, but all the docs for EventTrigger show it being triggered by an event coming off an existing FrameworkElement. I am now firing a RoutedEvent from my ViewModel but can't see how to get the XAML to subscribe: <EventTrigger RoutedEvent="my:NumbersViewModel.RightAnswer">
Mark Heath
+5  A: 

I had the opportunity to put this question to Microsoft's Josh Twist, who kindly took the time to provide an answer to this problem. The solution is to use a DataTrigger in combination with an enum in the ViewModel to launch the Storyboard, and this in turn requires putting the page into a ContentPresenter. To handle animation completion, a small amount of code behind was required to make a call into an ICommand on the ViewModel.

Read Josh's post here for a full description of the solution.

Mark Heath