Reputation: 566
I have different user controls defined as ItemSource DataTemplates for ListView, all sharing one ViewModel:
<UserControl>
<Grid>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding MyAwesomeProperty}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation>
some awesome animation
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</Style.Triggers>
</Style>
public class AwesomeViewModel : ViewModelBase
{
private bool myAwesomeProperty= false;
public bool MyAwesomeProperty
{
get { return myAwesomeProperty; }
set
{
if (myAwesomeProperty!= value)
{
myAwesomeProperty= value;
RaisePropertyChanged(() => MyAwesomeProperty);
}
}
}
}
Now, I want to start animation when MyAwesomeProperty changes to true. This is accomplished by DataTrigger. However, once animation is completed, I want to set the value of the MyAwesomeProperty back to false.
As this logic is shared by multiple UserControls having the same ViewModel, I want pure MVVM solution, without Animation.Completed callbacks in the code-behind. Is this possible?
Upvotes: 0
Views: 1553
Reputation: 3845
Here's a solution using Blend's interactivity library
First, right click References in your project, click Add Reference and under Framework add Microsoft.Expressions.Interaction
and System.Windows.Interactivity
.
After, add the following references to the top of your XAML file:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
Then you can do the following:
<Grid>
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding MyAwesomeProperty}" Value="True">
<ei:ControlStoryboardAction Storyboard="{StaticResource YourAwesomeStoryboard}" ControlStoryboardOption="Play"/>
<ei:ChangePropertyAction PropertyName="{Binding MyAwesomeProperty}" Value="False"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
</Grid>
Upvotes: 1
Reputation: 3845
One immediate solution I can see to this is by initiating the storyboard in code behind and subscribe to the storyboard completed event. You can start a storyboard in code like this:
Storyboard storyBoard = (Storyboard)this.Resources["YourStoryBoard"];
storyBoard.Begin();
And then subscribe to its event
storyboard.Completed += storyboard_Completed;
void storyboard_Completed(object sender, System.EventArgs e)
{
// your code here
}
Hope this was of help to you
Upvotes: 0
Reputation: 1268
Without code in your code-behind, you simply can't. I suggest you fire a Command on your ViewModel from code-behind to handle the logic. Like this you won't violate the MVVM pattern.
Upvotes: 0