Roman Plášil
Roman Plášil

Reputation: 1970

How to animate a resource in XAML?

In an XAML document, I have a gradient brush as a resource and a bunch of shapes that use this resource. I would like to animate the brush using a storyboard, but I don't know how to set the brush in resources as the target of storyboard. Simply using its name does not work, {StaticResource name} does not work either. Is it even possible?

I would prefer an XAML only solution, but if that does not work out, I'll use code-behind. If it lets me leave Storyboard.Target and Storyboard.TargetProperty unassigned.

EDIT: I would like to animate a gradient stop of the brush. The thing is that I can animate it easily when it's not a resource, but is applied directly on an object. I can do that by clicking in Expression Blend. I just don't know how to animate it when its a resource (i.e. what to put instead of the ?? in the code below (the storyboard was created for a rectangle))

code:
<UserControl.Resources>
    <LinearGradientBrush x:Key="Outline" EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="#7F7CE3FF" Offset="0"/>
        <GradientStop Color="#7F047695" Offset="1"/>
        <GradientStop Color="#FFFFFFFF" Offset="0.942"/>
    </LinearGradientBrush>
    <Storyboard x:Key="Glitter">
        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="??" Storyboard.TargetProperty="(Shape.Fill).(GradientBrush.GradientStops)[0].(GradientStop.Offset)">
            <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
            <SplineDoubleKeyFrame KeyTime="00:00:02.6000000" Value="0.529"/>
        </DoubleAnimationUsingKeyFrames>

    </Storyboard>
 ...

Upvotes: 5

Views: 4528

Answers (3)

Andrej
Andrej

Reputation: 991

It works when you animate the Background/Fill Property directly, using the name of the object (e.g. Rectangle) you want to animate as Storyboard.TargetName:

<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
    <Grid.Resources>
        <LinearGradientBrush x:Key="Outline" EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#7F7CE3FF" Offset="0"/>
            <GradientStop Color="#7F047695" Offset="1"/>
            <GradientStop Color="#FFFFFFFF" Offset="0.942"/>
        </LinearGradientBrush>
    </Grid.Resources>

    <Border Name="border" 
            Background="{StaticResource Outline}"
            Width="200" Height="200" />
</Grid>

<Window.Triggers>
    <EventTrigger RoutedEvent="Window.Loaded">
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                                               Storyboard.TargetName="border" 
                                               Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Offset)">
                    <SplineDoubleKeyFrame KeyTime="00:00:0" Value="0"/>
                    <SplineDoubleKeyFrame KeyTime="00:00:1" Value="1"/>
                </DoubleAnimationUsingKeyFrames>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
</Window.Triggers>

Edit

From code behind it seems to be totally possible:

XAML:

<Grid Name="grid">
    <Grid.Resources>
        <LinearGradientBrush x:Key="Outline" EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#7F7CE3FF" Offset="0"/>
            <GradientStop Color="#7F047695" Offset="1"/>
            <GradientStop Color="#FFFFFFFF" Offset="0.942"/>
        </LinearGradientBrush>
    </Grid.Resources>

    <Border Background="{StaticResource Outline}"
            Width="100" Height="100" HorizontalAlignment="Left" />

    <Border Background="{StaticResource Outline}"
            Width="100" Height="100" HorizontalAlignment="Right" />
</Grid>

C# code behind:

        LinearGradientBrush b = grid.Resources["Outline"] as LinearGradientBrush;

        b.GradientStops[0].BeginAnimation(GradientStop.OffsetProperty, new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(1))));

Upvotes: 4

Justin Niessner
Justin Niessner

Reputation: 245389

Not sure exactly what you're trying to animate inside of the brush, but animating Brush resources can be very tricky. I don't have time to type everything out, but here's a little 'tutorial' on how to handle it:

Animating Brushes with ObjectAnimationUsingKeyFrames

Upvotes: 0

Andrej
Andrej

Reputation:

You cannot animate Properties of the type Brush, you can only animate types that have an appropiate Animation Class, for example DoubleAnimation, PointAnimation or ColorAnimation (note that the last one animates Properties of the type Color, not Brush).

However, some Brushes have DependencyProperties of the type double, that you could animate, for example the StartPoint and EndPoint Properties of the LinearGradientBrush-Class.

If you can elaborate on what the animation should do exactly, maybe we could find a workaround.

Edit: To animate the Brush it would have to be declared in the scope of your Animation-Trigger, e.g. in the Data- or ControlTemplate. Animating a Resource via its key will not work.

Upvotes: 1

Related Questions