如何在 XAML 中為資源設置動畫? (How to animate a resource in XAML?)


問題描述

如何在 XAML 中為資源設置動畫? (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>
 ...

‑‑‑‑‑

參考解法

方法 1:

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

方法 2:

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.

方法 3:

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

(by Roman PlášilAndrejAndrejJustin Niessner)

參考文件

  1. How to animate a resource in XAML? (CC BY‑SA 3.0/4.0)

#animation #wpf #storyboard #xaml #resources






相關問題

Iphone app PNG 序列動畫 - 如何在不崩潰的情況下以最佳方式使用 OPENgle (Iphone app PNG sequence animation - How to use OPENgle optimally without crashing)

jquery切換幻燈片和切換旋轉動畫 (jquery toggle slide and toggle rotation animate)

如何在三次貝塞爾方法上禁用 css3 過渡鼠標離開效果? (How to disable css3 transition mouseleave effect on cubic-bezier method?)

Android:故事書(動畫、聲音、圖片) (Android: Storybooks (animation, sounds, pictures))

JQuery 動畫凌亂 (JQuery Animations Messy)

拉斐爾對角變換對象和無限setIntervals (Raphael transform object diagonally and infinite setIntervals)

使用 mouseover 和 mouseout 時避免生澀的動畫 (Avoiding jerky animation when using mouseover and mouseout)

在 C 中復制 Spinrite 動畫效果 (Replicating Spinrite Animation Effect in C)

將樣式作為參數傳遞給 jquery animate (passing style as argument to jquery animate)

如何設置 UIButton 的圖像並隨後將其刪除(動畫) (How to setImage of a UIButton and subsequently remove it (animation))

單擊消息後的 MessageKit 動畫 (MessageKit animation after click on message)

連續貝塞爾動畫,不繼承變化時的緩動功能 (Continuous bezier animation without inheriting easing-function on change)







留言討論