1
votes

I would like to add a fade out animation when a ToggleButton IsChecked=false and IsMouseOver is deactivating.

I have a toggle button with a custom control template.

The following triggers are setup and work great.

  • When IsChecked=true display background opacity=1
  • When IsMouseOver=true display background opacity=1

                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Opacity" TargetName="innerRectangle" Value="1"/>
                    </Trigger>
    
                    <Trigger Property="IsChecked" Value="True">
                        <Setter Property="Opacity" TargetName="innerRectangle" Value="1"/> 
                    </Trigger>
                </ControlTemplate.Triggers>
    

However, now I want to add a fade out animation when the ToggleButton is NOT checked and IsMouseOver is deactivating.

I've created a storyboard animation which changes the opacity value from 1 to 0 in 100ms:

<Storyboard x:Key="OnMouseOut">
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="innerRectangle">
        <EasingDoubleKeyFrame KeyTime="0" Value="1"/>
        <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0"/>
      </DoubleAnimationUsingKeyFrames></Storyboard>

What I've Tried

I added a EnterAction and ExitAction to the IsMouseOver trigger and that performs the intented effect. However, if the ToggleButton is checked I do not want the animation to run.

   <Trigger Property="IsMouseOver" Value="True">
                                <Trigger.EnterActions>
                                    <BeginStoryboard x:Name="OnMouseIn_BeginStoryboard" Storyboard="{StaticResource OnMouseIn}"/>
                                </Trigger.EnterActions>
                                <Trigger.ExitActions>
                                    <BeginStoryboard Storyboard="{StaticResource OnMouseOut}"/>
                                </Trigger.ExitActions>
                                <Setter Property="Opacity" TargetName="innerRectangle" Value="1"/>
                            </Trigger>

What I've Tried Part 2

Using a MultiTrigger doesn't remedy the issue.

 <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                    <Condition Property="IsChecked" Value="False"/>
                                </MultiTrigger.Conditions>
                                <MultiTrigger.EnterActions>
                                    <BeginStoryboard x:Name="OnMouseIn_BeginStoryboard" Storyboard="{StaticResource OnMouseIn}"/>
                                </MultiTrigger.EnterActions>
                                <MultiTrigger.ExitActions>
                                    <BeginStoryboard Storyboard="{StaticResource OnMouseOut}"/>
                                </MultiTrigger.ExitActions>
                                <Setter Property="Opacity" TargetName="innerRectangle" Value="1"/>
                            </MultiTrigger>
1
Have you tried using <StopStoryboard BeginStoryboardName="OnMouseIn_BeginStoryboard"/> in your ExitActions? I've used that to rollback fade in Opacity when the condition is no longer met.KornMuffin

1 Answers

0
votes

This just looks crazy, but it works. Basically, I created an identical story board with a different name when IsChecked is exiting. On Hover I cancel this secondary storyboard.

 <ControlTemplate.Triggers>
                        <MultiTrigger>
                            <MultiTrigger.Conditions>
                                <Condition Property="IsMouseOver" Value="True"/>
                                <Condition Property="IsChecked" Value="False"/>
                            </MultiTrigger.Conditions>
                            <MultiTrigger.EnterActions>
                                <StopStoryboard BeginStoryboardName="OnMouseOut_BeginStoryboard2"/>
                                <BeginStoryboard x:Name="OnMouseIn_BeginStoryboard" Storyboard="{StaticResource OnMouseIn}"/>
                            </MultiTrigger.EnterActions>
                            <MultiTrigger.ExitActions>
                                <BeginStoryboard x:Name="OnMouseOut_BeginStoryboard" Storyboard="{StaticResource OnMouseOut}"/>
                            </MultiTrigger.ExitActions>
                            <Setter Property="Opacity" TargetName="innerRectangle" Value="1"/>
                        </MultiTrigger>

                        <Trigger Property="IsChecked" Value="True">
                            <Trigger.ExitActions>
                                <StopStoryboard BeginStoryboardName="OnMouseOut_BeginStoryboard"/>
                                <StopStoryboard BeginStoryboardName="OnMouseIn_BeginStoryboard"/>
                                <BeginStoryboard x:Name="OnMouseOut_BeginStoryboard2" Storyboard="{StaticResource OnMouseOut}"/>

                            </Trigger.ExitActions>
                            <Trigger.EnterActions>
                                <StopStoryboard BeginStoryboardName="OnMouseOut_BeginStoryboard"/>
                                <StopStoryboard BeginStoryboardName="OnMouseIn_BeginStoryboard"/>
                            </Trigger.EnterActions>
                            <Setter Property="Opacity" TargetName="innerRectangle" Value="1"/>
                        </Trigger>

                    </ControlTemplate.Triggers>