Hussein Khalil
Hussein Khalil

Reputation: 1615

How to launch an animation defined in a Style from a Control implementing it?

I created a state in a Style named "Error" with an attached animation in a storyboard.

I would like to be able to launch that animation from a Control that uses that Style, whenever a certain condition is met.

For example, when a property in my View's DataContext is set to a certain value.

How exactly can I launch the storyboard defined in the control's Style ?

Upvotes: 0

Views: 101

Answers (3)

Hussein Khalil
Hussein Khalil

Reputation: 1615

I ended up creating a class that will hold all of my controls' validation dependency properties:

public class ValidationProperties
{
     #region IsValid Dependency Property

    /// <summary>
    /// An attached dependency property which provides an
    /// </summary>
    public static readonly DependencyProperty IsValidProperty;

    /// <summary>
    /// Gets the <see cref="IsValidProperty"/> for a given
    /// <see cref="DependencyObject"/>, which provides an
    /// </summary>
    public static bool GetIsValid(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsValidProperty);
    }

    /// <summary>
    /// Sets the attached <see cref="IsValidProperty"/> for a given
    /// <see cref="DependencyObject"/>, which provides an
    /// </summary>
    public static void SetIsValid(DependencyObject obj, bool value)
    {
        obj.SetValue(IsValidProperty, value);
    }

     #endregion IsValid Dependency Property

    static ValidationProperties()
    {
        // Register attached dependency property
        IsValidProperty = DependencyProperty.RegisterAttached("IsValid",
                                                            typeof(bool),
                                                            typeof(ValidationProperties), 
                                                            new FrameworkPropertyMetadata(true));
    }
}

Following this, I modified the style to launch the animation depending on the value of that property for the control that uses the style:

(...)

<Trigger Property="AttachedProperties:ValidationProperties.IsValid" Value="false">
    <Trigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource ControlIsInvalid}"/>
    </Trigger.EnterActions>
</Trigger>

(...)

I finally bound the Dependency Property on the Control that uses the Style to the value in the Model (via the View-Model):

<TextBox x:Name="UsernameTextbox"
       (...)
       AttachedProperties:ValidationProperties.IsValid="{Binding SessionHandler.SessionUser.UsernameIsValid}"/>

Upvotes: 1

louie
louie

Reputation: 83

Here it is how you do it from XAML using Triggers:

<Style TargetType="Button" x:Key="MyStyle">
            <Style.Resources>
                <Storyboard x:Key="MyGetFocusAnimation">
                    <DoubleAnimation Storyboard.TargetProperty="Height"
                                     To="50"
                                     Duration="0:0:.3" />
                </Storyboard>
                <Storyboard x:Key="MyLoseFocusAnimation">
                    <DoubleAnimation Storyboard.TargetProperty="Height"
                                     To="30"
                                     Duration="0:0:.3" />
                </Storyboard>
            </Style.Resources>
            <Style.Triggers>
                <Trigger Property="IsMouseOver"
                         Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard Storyboard="{StaticResource MyGetFocusAnimation}" />
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard Storyboard="{StaticResource MyLoseFocusAnimation}" />
                    </Trigger.ExitActions>
                </Trigger>
                <Trigger Property="IsKeyboardFocusWithin"
                         Value="True">
                    <Trigger.EnterActions>
                        <BeginStoryboard Storyboard="{StaticResource MyGetFocusAnimation}" />
                    </Trigger.EnterActions>
                    <Trigger.ExitActions>
                        <BeginStoryboard Storyboard="{StaticResource MyLoseFocusAnimation}" />
                    </Trigger.ExitActions>
                </Trigger>
            </Style.Triggers>
        </Style>

After you have defined the style like above you simply need to tell the button what style to use:

<Button Content="Content" Height="20" Width="100" Style="{StaticResource MyStyle}"/>

Upvotes: 1

Ucodia
Ucodia

Reputation: 7700

In the code behind of the control just do

Storyboard myStoryboard = this.FindResource("NameOfMyStoryBoard") as Storyboard;

if(myStoryboard != null)
{
    myStoryboard.Begin();
}

If your Storyboard is not set as a resource but is embedded in your style, declare it as a resource and reference it in your style.

MSDN documentation: Storyboard

Upvotes: 2

Related Questions