views:

672

answers:

3

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>
 ...
A: 

Hi,

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.

A: 

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

Justin Niessner
+2  A: 

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))));
Andrej
Yep, this works, but I have multiple shapes using that brush, so I thought I could do it all at once.
Roman Plášil
As I said, I don't think it is possible to animate objects that are stored in the resources.
Andrej
I added another sample, where I animate the brush via code-behind. This seems to be no problem at all.
Andrej