Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate a resource in XAML?

Tags:

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>
 ...
like image 475
Roman Plášil Avatar asked Jun 26 '09 13:06

Roman Plášil


1 Answers

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))));
like image 90
Andrej Avatar answered Oct 13 '22 09:10

Andrej