WPF Conflicting animations
I have two animations that controls the color of the border of a TextBox. One animation changes the color from the default yellow to blue, and one animation changes the color back to the default. These animations are started with triggers on IsFocused. This works fine.
Now I want the same animations to be trigged by IsMouseOver as well. My desired behavior is that the border of the TextBox should be blue if it has focus or if the mouse hovers over it, otherwise it should be yellow. And there should be an animated transition between the states.
As mentioned, to change color with an animation when the TextBox gets or loses focus is not a problem. Neither is there a problem changing the color when the mouse moves over the TextBox. The problem is having BOTH. Then there is a conflict...
How can I have both these animations?
Here's some code with both animations, but that does NOT work as I want it to due to the conflict. What happens is that if I hover over the TextBox once the animation will never run on IsFocused again...
<TextBox Width="200" Height="140" BorderBrush="Yellow" BorderThickness="4">
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Resources>
<Storyboard x:Key="RecievedFocusOrMouseOverAnimation">
<ColorAnimation
Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)"
To="Blue"
Duration="0:0:0.2" />
</Storyboard>
<Storyboard x:Key="LostFocusOrMouseOutAnimation">
<ColorAnimation
Storyboard.TargetProperty="BorderBrush.(SolidColorBrush.Color)"
To="Yellow"
Duration="0:0:0.2" />
</Storyboard>
</Style.Resources>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="IsFocusedTrueBeginStoryBoard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Name="IsFocusedFalseBeginStoryBoard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Name="IsMouseOverTrueBeginStory开发者_开发百科board" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Name="IsMouseOverFalseBeginStoryboard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
I would suggest you try to use a MultiDataTrigger with an OR condition like described here. Your code should be something like this:
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Value="True">
<Condition.Binding>
<MultiBinding Converter="{StaticResource BooleanOr}">
<Binding Path="IsMouseOver" RelativeSource="{RelativeSource self}" />
<Binding Path="IsFocused" RelativeSource="{RelativeSource self}" />
</MultiBinding>
</Condition.Binding>
</Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.EnterActions>
<BeginStoryboard Name="IsFocusedTrueBeginStoryBoard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" />
</MultiDataTrigger.EnterActions>
<MultiDataTrigger.ExitActions>
<BeginStoryboard Name="IsFocusedFalseBeginStoryBoard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" />
</MultiDataTrigger.ExitActions>
</MultiDataTrigger>
BooleanOr
is a IMultiValueConverter
that computes an OR between all its arguments (you can find it in the code attached to the article in the link).
It seems that you need to Stop the potential running Storyboards before you begin a new one. Try this
<Trigger Property="IsFocused" Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="IsMouseOverTrueBeginStoryboard"/>
<StopStoryboard BeginStoryboardName="IsMouseOverFalseBeginStoryboard"/>
<BeginStoryboard Name="IsFocusedTrueBeginStoryBoard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Name="IsFocusedFalseBeginStoryBoard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<StopStoryboard BeginStoryboardName="IsFocusedTrueBeginStoryBoard"/>
<StopStoryboard BeginStoryboardName="IsFocusedFalseBeginStoryBoard"/>
<BeginStoryboard Name="IsMouseOverTrueBeginStoryboard" Storyboard="{StaticResource RecievedFocusOrMouseOverAnimation}" />
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Name="IsMouseOverFalseBeginStoryboard" Storyboard="{StaticResource LostFocusOrMouseOutAnimation}" />
</Trigger.ExitActions>
</Trigger>
精彩评论