61

我需要帮助才能做出正确的决定。当某些事件发生时,我需要为我的用户控件的背景颜色设置动画。当它是时,我只想改变背景 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);
4

8 回答 8

89

我会用 aEventTrigger和 a ColorAnimation

在此示例中,a在事件中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>
于 2013-01-04T14:26:08.313 回答
31

注意,如果您的背景是冻结的实例,您可能会收到 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);

MSDN 上的可冻结对象概述

于 2013-10-21T15:03:08.283 回答
9
        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 并绑定到它;//玩得开心!

于 2014-03-08T20:55:15.767 回答
3

这是一组附加属性,如果您遇到可冻结的问题,可以使用这些属性。

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>
于 2016-03-10T15:47:29.717 回答
0

这对我来说效果很好。

我在按钮中有一条路径(它画了一个“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 语法”和“ Storyboard.TargetProperty ”。

于 2016-05-20T15:00:25.270 回答
0

这篇文章帮助了我。但是如果是像原来的问题所说的那样在 1 秒后改变颜色,

 ColorAnimation animation;
    animation = new ColorAnimation();
    animation.AutoReverse =true;
于 2016-03-31T15:08:25.660 回答
-1

在 WPF 中,使用动画可能会更好。表情混合具有相对的动画/行为。

于 2013-01-04T14:08:47.493 回答
-8

您可以使用DoubleAnimation以下方式更改颜色:

<Storyboard>
    <DoubleAnimation Storyboard.TargetProperty="Background"
                            From="0.0"
                            Duration="0:0:2"
                            To="1.0" />                        
</Storyboard>

希望能帮助到你

于 2013-01-04T14:11:42.543 回答