WPF ColorAnimation for a Brush property
Asked Answered
F

2

15

I wonder if someone can help me - I've got a label which I need to be able to cross-fade between any 2 colors when a method is called in the code behind.

My best attempt so far:

Private OldColor as Color = Colors.White
Sub SetPulseColor(ByVal NewColor As Color)
    Dim F As New Animation.ColorAnimation(OldColor, NewColor, New Duration(TimeSpan.Parse("00:00:01")))
    OldColor = NewColor
    F.AutoReverse = False
    PulseLogo.BeginAnimation(Label.ForegroundProperty, F)

End Sub

The problem I have is that ColorAnimation returns a Media.Color and The property type for Foreground is Brush.

I know how to create the appropriate brush but not how to do it in an animation.

From Googling, it seems I need a converter:

<ValueConversion(GetType(SolidColorBrush), GetType(SolidColorBrush))> _
Public Class ColorConverter
    Implements IValueConverter

Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.Convert
        Dim Color As Color = DirectCast(value, Color)
        Return New SolidColorBrush(Color)
    End Function

    Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements System.Windows.Data.IValueConverter.ConvertBack
        Return Nothing
    End Function

End Class

but all the examples I've seen bind it to the animation in XAML - And I'd like to do it in the code behind...

Can someone please point me in the right direction?

Thanks

Furrow answered 12/2, 2010 at 0:4 Comment(0)
N
22

The usual solution to this is not to use a converter, but instead to animate the Color of the Brush. However, to do this you need a PropertyPath, which in turn means you need a storyboard:

Storyboard s = new Storyboard();
s.Duration = new Duration(new TimeSpan(0, 0, 1));
s.Children.Add(F);

Storyboard.SetTarget(F, PulseLogo);
Storyboard.SetTargetProperty(F, new PropertyPath("Foreground.Color"));

s.Begin();

(pardon C# syntax)

Note the property path in the SetTargetProperty call, which traverses down through the Foreground property and into the resulting brush's Color property.

You can also use this technique to animate individual gradient stops in a gradient brush, etc.

Niu answered 12/2, 2010 at 0:38 Comment(4)
That's really elegant - I'll try it now. Edit Error: Cannot animate the 'Color' property on 'System.Windows.Media.SolidColorBrush' because the object is sealed or frozen. [My code]: Dim br As SolidColorBrush = DirectCast((PulseLogo.Foreground), SolidColorBrush) PulseLogo.Foreground.BeginAnimation(SolidColorBrush.ColorProperty, F) 'Thanks for any helpFurrow
Sorry, man, I messed up. I've only done this with storyboards before and I naively assumed I could directly translate that into a BeginAnimation call, which was wrong. I've updated the answer, now with actual *gasp* honest-to-goodness tested code -- hope this works better for you.Niu
No worries for the C# - They're so similar, it's little more than a dialect :) Thanks for the updated solution - it works flawlessly.Furrow
+1; Storyboard s = new Storyboard(); -- missing parenthesis and Timespan with capital S :)Mesozoic
C
0
            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 are class of Color, timeSpan is Class of TimeSpan, BackGroundCellGrid is class of Grid;

//no need to create SolidColorBrush and binding to it in XAML; //have fun!

Cavallaro answered 8/3, 2014 at 20:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.