Animate a button background color on error
To indicate an error, I'd like to temporarily change the background color of a button. I'm new to WPF animations and couldn't find a simple example to proceed from. And to further complicate matters, I'm using a Trigger to deal with error notification.
So here's my XAML, and I'd like to know how to replace the Background Setter with an animation (say, blink red three times in five seconds or something like that).
<UserControl>
<UserControl.Resources>
<Style x:Key="ErrorStyle" TargetType="Button">
<!--Clear the default error template (a red border)-->
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<AdornedElementPlaceholder />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent开发者_开发技巧}" />
<!--TODO: Replace with animation-->
<Setter Property="Background" Value="Orange"/>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Button Command="{Binding ProgramCommand, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"
Style="{StaticResource ErrorStyle}">
_Program
</Button>
</Grid>
</UserControl>
I'm also open to suggestions of better (simple) error notification.
You can use Trigger.EnterActions
for that.
<Trigger Property="Validation.HasError" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.Color" Duration="0:0:0.3"
From="White" To="Red" RepeatBehavior="3x" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
(Assumes the background to be a SolidColorBrush
, since the Storyboard.TargetProperty
points to its Color
property)
For gradients you can animate a specific stop's color as well, e.g.
<TextBox Text="{Binding TestInt}">
<TextBox.Background>
<LinearGradientBrush>
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
</TextBox.Background>
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" Duration="0:0:0.3"
From="White" To="Red" RepeatBehavior="3x" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
Thanks to @H.B.'s answer, here's my final code. You'll notice that, instead of setting the Button's Background to a SolidColor, I kludged in a color change at each gradient of the default button brush. This creates an effect that turns the entire button red, but allows it to revert back to its normal gradient look.
<UserControl>
<UserControl.Resources>
<Style Key="ErrorStyle" TargetType="Button">
<!--Clear the default error template (a red border)-->
<Setter Property="Validation.ErrorTemplate">
<Setter.Value>
<ControlTemplate>
<AdornedElementPlaceholder />
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="Validation.HasError" Value="True">
<Setter Property="ToolTip"
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[0].Color" To="Red" Duration="0:0:0.5" AutoReverse="True" RepeatBehavior="3x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[1].Color" To="Red" Duration="0:0:0.5" AutoReverse="True" RepeatBehavior="3x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[2].Color" To="Red" Duration="0:0:0.5" AutoReverse="True" RepeatBehavior="3x" />
<ColorAnimation Storyboard.TargetProperty="Background.GradientStops[3].Color" To="Red" Duration="0:0:0.5" AutoReverse="True" RepeatBehavior="3x" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Button Command="{Binding ProgramCommand, ValidatesOnExceptions=True, ValidatesOnDataErrors=True}"
Style="{StaticResource ErrorStyle}">
_Program
</Button>
</Grid>
</UserControl>
<Trigger Property="Validation.HasError" Value="True">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="Background" From="White"
To="Red" Duration="0:0:1" AutoReverse="True" RepeatBehavior="3x"/>
</Storyboard>
</BeginStoryboard>
</Trigger>
精彩评论