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 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>
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>
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>
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>