c# wpf animation colors coloranimation

c# - Color de fondo animado Wpf



animation colors (8)

Aquí hay un conjunto de propiedades adjuntas que se pueden usar si se encuentra con problemas con 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); } } }

Uso:

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

Necesito ayuda para tomar la decisión correcta. Necesito animar un color de fondo de mi control de usuario cuando ocurre algún evento. Cuando es así, quiero cambiar el fondo solo por 1 segundo y luego volverlo atrás. ¿A qué camino debería ir? Use la animación de color o el temporizador o puede hacerlo de otra forma.

Resuelto ¡Gracias a todos! Esto funciona bien para mí:

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


En WPF, el uso de la animación puede ser mejor. La mezcla de expresión tiene la animación / comportamiento relativo.


Esta publicación me ayudó. Pero si se trata de cambiar el color de nuevo después de 1 segundo, como dice la pregunta original,

ColorAnimation animation; animation = new ColorAnimation(); animation.AutoReverse =true;


Esto funcionó bien para mí.

Tengo un camino dentro de un botón (dibuja una "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"/>

Al pasar el mouse, quiero que la cruz se ponga roja, así que agrego:

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

Lo más confuso sobre esto son los corchetes dentro de Storyboard.TargetProperty . Si quita los corchetes, nada funciona.

Para obtener más información, consulte " propertyName Grammar " y " Storyboard.TargetProperty ".


Puede usar DoubleAnimation para cambiar el color de esta manera:

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

Espero eso ayude


Tenga cuidado, podría recibir una System.InvalidOperationException si su fondo es una instancia congelada.

No se puede animar la propiedad ''Color'' en ''System.Windows.Media.SolidColorBrush'' porque el objeto está sellado o congelado.

Para corregir este mensaje, asigne el fondo de su control a una instancia no congelada.

// Do not use a frozen instance this.elGrid.Background = new SolidColorBrush(Colors.Orange); this.elGrid.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);

Descripción general de Freezable Objects en MSDN


Utilizaría un EventTrigger con ColorAnimation .

En este ejemplo, Button Brackground pone verde en un evento MouseLeave . Este código es, afortunadamente, similar a lo que pueda necesitar.

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


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 son clases de Color, timeSpan es Clase de TimeSpan, BackGroundCellGrid es clase de Grid;

// no es necesario crear SolidColorBrush y vincularlo en XAML; //¡que te diviertas!