WPF Storyboard Trigger on property changed

14,152

Solution 1

Yes, you can do that.

Add a DataTrigger and bind to the respective property. Here's an example:

<DataTemplate.Triggers>
    <DataTrigger Binding="{Binding Path=MyProperty}" Value="True">
        <BeginStoryboard Storyboard="{StaticResource myStoryboard}"/>
    </DataTrigger>
</DataTemplate.Triggers>

You can set the value to test for to anything you want. So you could set the storyboard to begin when your value changes to false. You can add as many DataTriggers (or other triggers) as you want.

Notice that in my example I reference a dummy property and storyboard.

When the property changes, the binding will be updated and will fire the trigger because of the databinding.

This technique should also work at startup.

Solution 2

Similar to the poster above, I also used a DataTrigger and then bound it to a property in my ViewModel. The one thing I found confusing was where to put the data trigger. I put it directly in the root node (i.e. Window). I created it using Expression Blend which took care of the tag naming details for me.

Also make sure to include in your project a reference to "Microsoft.Expression.Interactions"

XAML: (this goes directly in the root node)

<Window
   xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
   xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
   x:Name="window" >

    ...

    <i:Interaction.Triggers>
      <ei:DataTrigger Binding="{Binding FlashingBackground, Mode=OneWay}" Value="ON">
        <ei:ControlStoryboardAction Storyboard="{StaticResource MyAnimation}"     
                                                ControlStoryboardOption="Play"/>
      </ei:DataTrigger>
    </i:Interaction.Triggers>

    ...
</Window>

ViewModel:

 private void TurnOnFlashingBackround()
    {
        FlashingBackground = "ON";
    }

    private string _FlashingBackround = "OFF";

    public string FlashingBackground
    {
        get { return _FlashingBackround; }

        private set
        {
            if (FlashingBackground == value)
            {
                return;
            }

            _FlashingBackround = value;
            this.OnPropertyChanged("FlashingBackground");
        }
    }

    public new event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged(string propertyName)
    {
        if (this.PropertyChanged != null)
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Finally, the Viewmodel must inherit from "INotifyPropertyChanged"

Share:
14,152
Raven
Author by

Raven

https://github.com/AnderssonPeter

Updated on June 11, 2022

Comments

  • Raven
    Raven almost 2 years

    I have a DataTemplate that is for a class that implements INotifyPropertyChanged. Is there any way to trigger a storyboard when a property changes and a different storyboard on different values (its a bool in this case)?

    And is there any way to trigger a storyboard on startup depending on values on the class that the datatemplate is made for?

  • Raven
    Raven about 15 years
    will this work even if all values are set when the listbox gets the object?
  • Alex Paven
    Alex Paven almost 13 years
    Actually this example uses the Blend triggers, which are quite different from the built-in WPF triggers. Yet they are named the same. Just different namespaces. In a sense, the Blend ones could be considered 'attached' triggers, I guess, while the built-in ones have very specific rules about where they can be placed.
  • swinefeaster
    swinefeaster over 12 years
    Where in the xaml do we add this?
  • Josh G
    Josh G about 9 years
    @swinefeaster: Anywhere inside of a DataTemplate. Per the original poster, he's already working within a DataTemplate. DataTemplates are defined as resources, either locally within some component or at the top of a UserControl.
  • Nicolas
    Nicolas over 5 years
    The <BeginStoryboard .. element is not accepted within the <DataTrigger ... element for me: a value of type "BeginStoryboard" kann not assigned to a collection or dictionary of type "SetterBaseCollection" (free translation). Why is this?