Wpf animate background color

前端 未结 8 2044
生来不讨喜
生来不讨喜 2020-11-30 02:41

I need help in taking right decision. I need to animate a background color of my user control when some event happens. When it is, I want to change the background just for 1

相关标签:
8条回答
  • 2020-11-30 03:17

    Watch out, you could received a System.InvalidOperationException if your background is a frozen instance.

    Cannot animate the 'Color' property on 'System.Windows.Media.SolidColorBrush' because the object is sealed or frozen.

    To correct this message assign the background of your control to a non-frozen instance.

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

    0 讨论(0)
  • 2020-11-30 03:27

    This post helped me. But if it is to change the color back after 1 second like the original question says,

     ColorAnimation animation;
        animation = new ColorAnimation();
        animation.AutoReverse =true;
    
    0 讨论(0)
  • 2020-11-30 03:28

    Here is a set of attached properties that can be used if you run into issues with freezables.

    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);
            }
        }
    }
    

    Usage:

    <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>
    
    0 讨论(0)
  • 2020-11-30 03:33

    You can use DoubleAnimation to change the color like this:

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

    Hope it helps

    0 讨论(0)
  • 2020-11-30 03:36

    In WPF ,Using animation maybe better. Expression blend have the relative animation/behaviour.

    0 讨论(0)
  • 2020-11-30 03:37

    I would use an EventTrigger with a ColorAnimation.

    In this example a Button Brackground goes green on a MouseLeave event. This code is hopefully similar to what you may need.

    <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>
    
    0 讨论(0)
提交回复
热议问题