Nicke Manarin
Nicke Manarin

Reputation: 3358

How to prevent animation from playing on control load?

Imagine a WPF control that has a trigger in which its EnterAction/ExitActions have a Storyboard inside.

In my case it's an Expander which animates the expand/collapse action based on the IsExpanded property.

Animation works normally on clicking, the issue starts if I set IsExpanded="True" by default, then on load the expander will animate to expand itself.


My first idea was to use VisualState and extend the Expander to avoid running the animations on load:

public class MyExpander : Expander
{
    static MyExpander()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyExpander), new FrameworkPropertyMetadata(typeof(MyExpander)));
    }

    public override void OnApplyTemplate()
    {
        VisualStateManager.GoToState(this, IsExpanded ? "Expanded" : "Collapsed", false);

        base.OnApplyTemplate();
    }

    protected override void OnExpanded()
    {
        VisualStateManager.GoToState(this, "Expanded", IsLoaded && IsVisible);

        System.Diagnostics.Debug.WriteLine($"Expand? {IsLoaded} && {IsVisible}, {IsInitialized}");

        base.OnExpanded();
    }

    protected override void OnCollapsed()
    {
        VisualStateManager.GoToState(this, "Collapsed", IsLoaded && IsVisible);

        base.OnCollapsed();
    }
}

And inside the ControlTemplate as child of the first FrameworkElement (in my case a Border):

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="ExpansionStates">
        <VisualStateGroup.Transitions>
            <VisualTransition From="Collapsed" To="Expanded">
                <!--<VisualTransition.GeneratedEasingFunction>
                    <CircleEase EasingMode="EaseInOut"/>
                </VisualTransition.GeneratedEasingFunction>-->
            </VisualTransition>

            <VisualTransition From="Expanded" To="Collapsed">
                <!--<VisualTransition.GeneratedEasingFunction>
                    <CircleEase EasingMode="EaseInOut"/>
                </VisualTransition.GeneratedEasingFunction>-->
            </VisualTransition>
        </VisualStateGroup.Transitions>

        <VisualState x:Name="Expanded">
            <Storyboard x:Name="ExpandStoryboard">
                <DoubleAnimation Storyboard.TargetName="PresenterScaleTransform" Storyboard.TargetProperty="ScaleY" Duration="0:0:0.2" To="1" BeginTime="0:0:0">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseInOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>

                <DoubleAnimation Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Opacity" Duration="0:0:0.05" To="1" BeginTime="0:0:0.15">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseInOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>

                <DoubleAnimation Storyboard.TargetName="SymbolRotateTransform" Storyboard.TargetProperty="Angle" Duration="0:0:0.2" To="180" BeginTime="0:0:0.1">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseIn"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>

                <ObjectAnimationUsingKeyFrames BeginTime="0:00:00" Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="{x:Static Visibility.Visible}" KeyTime="0:0:0"/>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>

        <VisualState x:Name="Collapsed">
            <Storyboard>
                <DoubleAnimation Storyboard.TargetName="PresenterScaleTransform" Storyboard.TargetProperty="ScaleY" Duration="0:0:0.2" To="0" BeginTime="0:0:0">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseInOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>

                <DoubleAnimation Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Opacity" Duration="0:0:0.1" To="0" BeginTime="0:0:0">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseInOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>

                <DoubleAnimation Storyboard.TargetName="SymbolRotateTransform" Storyboard.TargetProperty="Angle" Duration="0:0:0.2" To="0" BeginTime="0:0:0.1">
                    <DoubleAnimation.EasingFunction>
                        <CircleEase EasingMode="EaseIn"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>

                <ObjectAnimationUsingKeyFrames BeginTime="0:00:00" Storyboard.TargetName="ExpandSite" Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame Value="{x:Static Visibility.Collapsed}" KeyTime="0:0:0.2"/>
                </ObjectAnimationUsingKeyFrames>
            </Storyboard>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

I tried playing with the VisualTransition, adding more or less details, but it ends making it worse. With this config, at least the expander animates as expected when clicking. It just doesnt stop the animation from happening on load.

Upvotes: 2

Views: 29

Answers (0)

Related Questions