Wpf 动画背景颜色
Posted
技术标签:
【中文标题】Wpf 动画背景颜色【英文标题】:Wpf animate background color 【发布时间】:2012-12-18 23:19:18 【问题描述】:我需要帮助才能做出正确的决定。当某些事件发生时,我需要为我的用户控件的背景颜色设置动画。当它是时,我只想改变背景 1 秒钟,然后再把它转回来。我应该走哪条路?使用彩色动画或计时器,或者可以通过其他方式。
解决了。谢谢大家!这对我很有用:
ColorAnimation animation;
animation = new ColorAnimation();
animation.From = Colors.Orange;
animation.To = Colors.Gray;
animation.Duration = new Duration(TimeSpan.FromSeconds(1));
this.elGrid.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
【问题讨论】:
问题是非常开放的,因为它往往更多的是个人选择。我建议重新措辞问题或包括您尝试过的事情。 对不起,我添加了一个标签“动画”,它看起来像是自动更改的。 您至少应该发布一些代码/更多信息(哪个事件?您的 xaml 是什么样的?) 【参考方案1】:在 WPF 中,使用动画可能会更好。表情混合具有相关的动画/行为。
【讨论】:
【参考方案2】:您可以使用DoubleAnimation
更改颜色,如下所示:
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Background"
From="0.0"
Duration="0:0:2"
To="1.0" />
</Storyboard>
希望对你有帮助
【讨论】:
其实Background是一个Brush类型。 DoubleAnimation 用于为双精度类型设置动画。 这是真的 Kaus78。我从之前为 Label 控件定义的 ControlTemplate 中提取了这个 sn-p,并将 Opacity 替换为 Background 只是为了一个简单的示例。【参考方案3】:我会使用EventTrigger
和ColorAnimation
。
在此示例中,Button Brackground
在 MouseLeave
事件中变为绿色。希望此代码与您可能需要的代码相似。
<Button Content="Button" Height="75" HorizontalAlignment="Left" Margin="27,12,0,0" Name="btnImgBrush" VerticalAlignment="Top" Width="160" Background="LightGray">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation To="Green"
Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
FillBehavior="Stop"
Duration="0:0:1"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
【讨论】:
我的 XAML 无效,应该将Duration
改为 0:0:1
吗?
@Klaus78 (Button.Background).(SolidColorBrush.Color) 是什么意思?这里的括号作用是什么??
@Helic 我自己也这么问过。 MSDN 声明这是一个Single Property, Attached or Otherwise Type-Qualified
声明,请参阅docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/…
最适合填充属性。非常感谢,
尝试在 TargetProperty 上执行此操作:Storyboard.TargetProperty="(Control.Background).(SolidColorBrush.Color)"
,将 Button.Background 更改为 Control.Background。效果一样【参考方案4】:
注意,如果您的背景是冻结的实例,您可能会收到 System.InvalidOperationException。
无法为“System.Windows.Media.SolidColorBrush”上的“Color”属性设置动画,因为该对象已密封或冻结。
要更正此消息,请将控件的背景分配给未冻结的实例。
// Do not use a frozen instance
this.elGrid.Background = new SolidColorBrush(Colors.Orange);
this.elGrid.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
Freezable Objects Overview on MSDN
【讨论】:
这应该在添加到原始问题的代码中。【参考方案5】: ColorAnimation colorChangeAnimation = new ColorAnimation();
colorChangeAnimation.From = VariableColour;
colorChangeAnimation.To = BaseColour;
colorChangeAnimation.Duration = timeSpan;
PropertyPath colorTargetPath = new PropertyPath("(Panel.Background).(SolidColorBrush.Color)");
Storyboard CellBackgroundChangeStory = new Storyboard();
Storyboard.SetTarget(colorChangeAnimation, BackGroundCellGrid);
Storyboard.SetTargetProperty(colorChangeAnimation, colorTargetPath);
CellBackgroundChangeStory.Children.Add(colorChangeAnimation);
CellBackgroundChangeStory.Begin();
//VariableColour & BaseColour是Color的类,timeSpan是TimeSpan的类,BackGroundCellGrid是Grid的类;
//无需在 XAML 中创建 SolidColorBrush 并绑定到它; //玩得开心!
【讨论】:
【参考方案6】:如果遇到可冻结的问题,可以使用一组附加属性。
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
public static class Blink
public static readonly DependencyProperty WhenProperty = DependencyProperty.RegisterAttached(
"When",
typeof(bool?),
typeof(Blink),
new PropertyMetadata(false, OnWhenChanged));
public static readonly DependencyProperty FromProperty = DependencyProperty.RegisterAttached(
"From",
typeof(Color),
typeof(Blink),
new FrameworkPropertyMetadata(Colors.Transparent, FrameworkPropertyMetadataOptions.Inherits));
public static readonly DependencyProperty ToProperty = DependencyProperty.RegisterAttached(
"To",
typeof(Color),
typeof(Blink),
new FrameworkPropertyMetadata(Colors.Orange, FrameworkPropertyMetadataOptions.Inherits));
public static readonly DependencyProperty PropertyProperty = DependencyProperty.RegisterAttached(
"Property",
typeof(DependencyProperty),
typeof(Blink),
new PropertyMetadata(default(DependencyProperty)));
public static readonly DependencyProperty DurationProperty = DependencyProperty.RegisterAttached(
"Duration",
typeof(Duration),
typeof(Blink),
new PropertyMetadata(new Duration(TimeSpan.FromSeconds(1))));
public static readonly DependencyProperty AutoReverseProperty = DependencyProperty.RegisterAttached(
"AutoReverse",
typeof(bool),
typeof(Blink),
new PropertyMetadata(true));
public static readonly DependencyProperty RepeatBehaviorProperty = DependencyProperty.RegisterAttached(
"RepeatBehavior",
typeof(RepeatBehavior),
typeof(Blink),
new PropertyMetadata(RepeatBehavior.Forever));
private static readonly DependencyProperty OldBrushProperty = DependencyProperty.RegisterAttached(
"OldBrush",
typeof(Brush),
typeof(Blink),
new PropertyMetadata(null));
public static void SetWhen(this UIElement element, bool? value)
element.SetValue(WhenProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static bool? GetWhen(this UIElement element)
return (bool?)element.GetValue(WhenProperty);
public static void SetFrom(this DependencyObject element, Color value)
element.SetValue(FromProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static Color GetFrom(this DependencyObject element)
return (Color)element.GetValue(FromProperty);
public static void SetTo(this DependencyObject element, Color value)
element.SetValue(ToProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static Color GetTo(this DependencyObject element)
return (Color)element.GetValue(ToProperty);
public static void SetProperty(this UIElement element, DependencyProperty value)
element.SetValue(PropertyProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static DependencyProperty GetProperty(this UIElement element)
return (DependencyProperty)element.GetValue(PropertyProperty);
public static void SetDuration(this UIElement element, Duration value)
element.SetValue(DurationProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static Duration GetDuration(this UIElement element)
return (Duration)element.GetValue(DurationProperty);
public static void SetAutoReverse(this UIElement element, bool value)
element.SetValue(AutoReverseProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static bool GetAutoReverse(this UIElement element)
return (bool)element.GetValue(AutoReverseProperty);
public static void SetRepeatBehavior(this UIElement element, RepeatBehavior value)
element.SetValue(RepeatBehaviorProperty, value);
[AttachedPropertyBrowsableForChildren(IncludeDescendants = false)]
[AttachedPropertyBrowsableForType(typeof(UIElement))]
public static RepeatBehavior GetRepeatBehavior(this UIElement element)
return (RepeatBehavior)element.GetValue(RepeatBehaviorProperty);
private static void OnWhenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
var property = GetProperty((UIElement)d) ?? GetDefaultProperty(d);
if (property == null || !typeof(Brush).IsAssignableFrom(property.PropertyType))
if (DesignerProperties.GetIsInDesignMode(d))
if (property != null)
throw new ArgumentException($"Could not blink for d.GetType().Name.property.Name", nameof(d));
return;
AnimateBlink(e.NewValue as bool?, (UIElement)d, property);
private static DependencyProperty GetDefaultProperty(DependencyObject d)
if (d is Control)
return Control.BackgroundProperty;
if (d is Panel)
return Panel.BackgroundProperty;
if (d is Border)
return Border.BackgroundProperty;
if (d is Shape)
return Shape.FillProperty;
if (DesignerProperties.GetIsInDesignMode(d))
throw new ArgumentException($"Could not find property to blink for d.GetType().Name", nameof(d));
return null;
private static void AnimateBlink(bool? blink, UIElement element, DependencyProperty property)
if (element == null)
return;
if (blink == true)
var brush = element.GetValue(property);
element.SetCurrentValue(OldBrushProperty, brush);
element.SetValue(property, Brushes.Transparent);
var from = element.GetFrom();
var to = element.GetTo();
var sb = new Storyboard();
var duration = element.GetDuration();
var animation = new ColorAnimation(from, to, duration)
AutoReverse = element.GetAutoReverse(),
RepeatBehavior = element.GetRepeatBehavior()
;
Storyboard.SetTarget(animation, element);
Storyboard.SetTargetProperty(animation, new PropertyPath($"property.Name.(SolidColorBrush.Color)"));
sb.Children.Add(animation);
sb.Begin();
else
var brush = element.GetValue(OldBrushProperty);
element.BeginAnimation(property, null);
element.SetCurrentValue(property, brush);
用法:
<Grid>
<Grid.Resources>
<Style x:Key="BlinkWhenMouseOver"
TargetType="x:Type Border">
<Setter Property="local:Blink.When" Value="Binding IsMouseOver, RelativeSource=RelativeSource Self" />
<Setter Property="local:Blink.From" Value="Honeydew" />
<Setter Property="local:Blink.To" Value="HotPink" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="local:Blink.Property" Value="x:Static Border.BorderBrushProperty" />
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Border Style="StaticResource BlinkWhenMouseOver" Background="Transparent"/>
<Border Grid.Row="1"
local:Blink.From="Aqua"
local:Blink.To="Yellow"
local:Blink.When="Binding IsChecked,
ElementName=ToggleBlink" />
<ToggleButton x:Name="ToggleBlink"
Grid.Row="2"
Content="Blink" />
</Grid>
【讨论】:
【参考方案7】:这篇文章帮助了我。但是如果是像原来的问题所说的那样在 1 秒后改变颜色,
ColorAnimation animation;
animation = new ColorAnimation();
animation.AutoReverse =true;
【讨论】:
【参考方案8】:这对我很有效。
我有一个按钮内的路径(它画了一个“X”):
<Path x:Name="MyDeleteRowButton" Stroke="Gray" Grid.Row="0"
Data="M1,5 L11,15 M1,15 L11,5" StrokeThickness="2" HorizontalAlignment="Center"
Stretch="None"/>
鼠标悬停时,我想让十字变成红色,所以我添加:
<DataTemplate.Triggers>
<!-- Highlight row on mouse over, and highlight the delete button. -->
<EventTrigger RoutedEvent="ItemsControl.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!-- On mouse over, flicker the row to highlight it.-->
<DoubleAnimation
Storyboard.TargetProperty="Opacity"
From="0.5"
To="1"
Duration="0:0:0.250"
FillBehavior="Stop"/>
<!-- Highlight the delete button with red. -->
<ColorAnimation
To="Red"
Storyboard.TargetName="MyDeleteRowButton"
Storyboard.TargetProperty="(Stroke).(SolidColorBrush.Color)"
Duration="0:0:0.100"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<!-- Grey out the delete button. -->
<EventTrigger RoutedEvent="ItemsControl.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!-- Space is precious: "delete" button appears only on a mouseover. -->
<ColorAnimation
To="Gray"
Storyboard.TargetName="MyDeleteRowButton"
Storyboard.TargetProperty="(Stroke).(SolidColorBrush.Color)"
Duration="0:0:0.100"
FillBehavior="HoldEnd"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</DataTemplate.Triggers>
最令人困惑的是Storyboard.TargetProperty
中的括号。如果删除括号,则没有任何效果。
有关详细信息,请参阅“propertyName Grammar”和“Storyboard.TargetProperty”。
【讨论】:
以上是关于Wpf 动画背景颜色的主要内容,如果未能解决你的问题,请参考以下文章