我需要在多个地方使用相同的故事板,因此我将故事板放在了我的 Application.Resources 中。当我尝试执行情节提要时,唯一的问题是我需要引用我想要制作动画的目标。这是我的故事板:
<System:String x:Key="target">border2</System:String>
<Storyboard x:Key="stHeight">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(FrameworkElement.Height)"
Storyboard.TargetName="{DynamicResource target}">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="90">
<EasingDoubleKeyFrame.EasingFunction>
<CircleEase EasingMode="EaseOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
我为不同对象的高度设置动画的方式是通过更改动态资源目标。当故事板在当前窗口中时,我能够这样做。但是现在我想将它放在应用程序资源中,我不知道如何引用目标属性。
编辑
我之前发布的解决方案效果很好,但有时很难用代码创建复杂的动画。所以我想出的另一个替代解决方案是创建带有表情混合的故事板。所以我将一个随机控件拖动到表达式混合的主窗口并创建一个随机动画。假设动画如下:
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="90"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="103"/>
</DoubleAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="grid">
<EasingPointKeyFrame KeyTime="0:0:1" Value="0.75,0.5"/>
</PointAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="grid">
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="75"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
然后我复制该代码并将其粘贴到我的工作窗口中,而不是在 APP.XAML 中。
然后在我的代码中假设我有一个:
<Border Name="brdBorder" BorderBrush="Silver" BorderThickness="1" Margin="328,104,0,0" Background="#FFE52E2E" HorizontalAlignment="Left" Width="94" Height="100" VerticalAlignment="Top" >
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
</Border>
出于某种原因,变换组必须在那里才能为对象设置动画。无论如何,假设我的工作窗口中有那个边界,我想用我用表情混合创建的相同动画来制作它。我将在代码中做的是:
Storyboard sb1 = FindResource("Storyboard1") as Storyboard;
foreach (var child in sb1.Children)
{
Storyboard.SetTargetName(child, brdBorder.Name);
}
sb1.Begin(this);
然后我可以在我的工作窗口上为该边框设置动画。这样做的好处是我能够将相同的动画应用于多个对象(我认为这是创建资源的目的)当我尝试将情节提要放在资源字典或 app.xaml 中时,问题就来了文件。当我这样做时,c# 能够找到情节提要,但情节提要的属性是只读的,因此我收到错误:
Cannot set a property on object 'System.Windows.Media.Animation.DoubleAnimationUsingKeyFrames' because it is in a read-only state.
我想这样做的原因是将相同的动画应用于多个对象。一个变通的解决方案是使用代码构建基本动画,然后将更复杂的动画(如缓动函数等)保存为资源。让我告诉你我的意思。
在我的资源文件中,我放置了以下资源:
<EasingDoubleKeyFrame x:Key="pleaseWork">
<EasingDoubleKeyFrame.EasingFunction >
<BackEase EasingMode="EaseOut" Amplitude="1"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
在表达式混合中,您可以构建更复杂的缓动功能。然后使用后面的代码,我将创建一个基本的故事板:
DoubleAnimation animation = new DoubleAnimation();
animation.To = 336; // final value
//animation.From = 0;
//animation.BeginTime = TimeSpan.FromSeconds(0);
animation.Duration = new Duration(TimeSpan.FromSeconds(5)); // how much time should animation last
// here comes the magic:
// note that I can bind to EasingDoubleKeyFrame in my resource file in xaml
animation.EasingFunction = ((EasingDoubleKeyFrame)FindResource("pleaseWork")).EasingFunction; // apply the easing function
Storyboard.SetTarget(animation, groupBox1); // what object will be animated?
Storyboard.SetTargetProperty(animation, new PropertyPath(FrameworkElement.HeightProperty)); // what property will be animated
Storyboard sb = new Storyboard();
sb.Children.Add(animation);
sb.Begin();
这使我能够在多个对象上使用相同的故事板。