[英]Access Storyboard dynamically from code-behind?
I'm working on a Windows Phone app, but I believe this applies to Silverlight
as well.我正在开发 Windows Phone 应用程序,但我相信这也适用于
Silverlight
。 I want to create a Storyboard
(right now I'm creating it as a global variable in my code-behind page for testing) that changes a Rectangle
's Fill
property from transparent to red, and then back to transparent.我想创建一个
Storyboard
(现在我将它创建为我的代码隐藏页面中的全局变量以进行测试),它将Rectangle
的Fill
属性从透明更改为红色,然后再返回透明。 I'm going to be re-using this Storyboard
among multiple rectangles so I'd like to be able to access it and Begin()
it from the code-behind.我将在多个矩形中重新使用这个
Storyboard
,所以我希望能够从代码隐藏中访问它和Begin()
它。 I couldn't find any examples like this, so I gave it a shot with what I thought might work.我找不到任何这样的例子,所以我试了一下我认为可能有用的东西。
Initial setup:最初设定:
sb = new Storyboard();
turnOn= new ColorAnimation();
turnOn.From = Colors.Transparent;
turnOn.To = Colors.Red;
turnOn.Duration = new TimeSpan(0, 0, 0, 0, 500); //half second
turnOff= new ColorAnimation();
turnOff.From = Colors.Red;
turnOff.To = Colors.Transparent;
turnOff.Duration = new TimeSpan(0, 0, 0, 0, 500); //half second
Storyboard.SetTargetProperty(turnOn, new PropertyPath("(Rectangle.Fill)"));
Storyboard.SetTargetProperty(turnOff, new PropertyPath("(Rectangle.Fill)"));
sb.Children.Add(turnOn);
sb.Children.Add(turnOff);
canvas.Resources.Add("sb", sb); // this is the canvas where the rectangles will be
Then, at any time, if I have a Rectangle
instance, which will be on the Canvas
from above, I'd like to initiate the storyboard - which will turn the Rectangle
red, and then back to transparent:然后,在任何时候,如果我有一个
Rectangle
实例,它将从上面的Canvas
上,我想启动故事板 - 这将使Rectangle
变成红色,然后变回透明:
// Set the target to my current rectangle, and begin:
Storyboard.SetTarget(turnOn, myRectangle);
Storyboard.SetTarget(turnOn, myRectangle);
sb.Begin();
But, it throws the following exception on the sb.Begin()
line:但是,它会在
sb.Begin()
行上抛出以下异常:
InvalidOperationException was unhandled by user code An exception of type 'System.InvalidOperationException' occurred in System.Windows.ni.dll but was not handled in user code
InvalidOperationException was unhandled by user code System.Windows.ni.dll 中发生类型为“System.InvalidOperationException”的异常,但未在用户代码中处理
I'm hoping I'm not too far off here in my thinking, but maybe there is an easier way?我希望我的想法不会太远,但也许有更简单的方法? If not, can anyone see what I'm doing wrong?
如果没有,谁能看到我做错了什么?
UPDATE (SOLUTION):更新(解决方案):
I followed the example provided by @Josh Mackey and moved my Storyboard
into the XAML
page which I think will be cleaner anyway.我遵循了@Josh Mackey 提供的示例,并将我的
Storyboard
移到了XAML
页面,我认为无论如何它都会更清晰。 What I didn't notice before was the exception details stating that "ColorAnimation cannot be used to animate property Fill due to incompatible type."我之前没有注意到的是异常详细信息,指出“由于类型不兼容, ColorAnimation 不能用于为 Fill 属性设置动画”。 I was able to use @Josh Mackey's solution by changing my
ColorAnimation
to ColorAnimationUsingKeyFrames
.通过将我的
ColorAnimation
更改为ColorAnimationUsingKeyFrames
我能够使用@Josh Mackey 的解决方案。 New code:新代码:
<Canvas.Resources>
<Storyboard x:Name="sb">
<ColorAnimationUsingKeyFrames
Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
AutoReverse="True">
<EasingColorKeyFrame KeyTime="00:00:0" Value="Black" />
<EasingColorKeyFrame KeyTime="00:00:0.25" Value="Red" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Canvas.Resources>
I was able to only use one animation because I was able to set AutoReverse
to True
and I found this article which describes how I can access the Storyboard
in my code-behind like this:我只能使用一个动画,因为我能够将
AutoReverse
设置为True
,我发现这篇文章描述了如何在我的代码隐藏中访问Storyboard
,如下所示:
sb.Stop();
sb.SetValue(Storyboard.TargetNameProperty, myRectangle.Name);
sb.Begin();
And now it works as expected!现在它按预期工作了!
Any particular reason you can't define your storyboard in the XAML file?您无法在 XAML 文件中定义故事板的任何特殊原因?
The following example is from a WP7 project of mine.以下示例来自我的 WP7 项目。 Its a usercontrol but but same process applies, just replace UserControl with whatever you're using.
它是一个用户控件,但适用相同的过程,只需将 UserControl 替换为您正在使用的任何内容。
<UserControl.Resources>
<Storyboard x:Key="aniFlipToBack">
<DoubleAnimation Storyboard.TargetName="LayoutRoot"
Completed="DoubleAnimation_Completed"
Storyboard.TargetProperty="(Grid.Projection).(PlaneProjection.RotationY)"
From="0" To="180" Duration="0:0:0.5" RepeatBehavior="1x" />
<ObjectAnimationUsingKeyFrames
Duration="0:0:0.5"
Storyboard.TargetName="gridFront" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.25" Value="Collapsed" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames
Duration="0:0:0.5"
Storyboard.TargetName="gridBack" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0.25" Value="Visible" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
And to use it:并使用它:
Storyboard storyBoard = (Storyboard)this.Resources["aniFlipToBack"];
storyBoard.Begin();
(I would have commented but apparently my rep isn't high enough, so I'll post an answer with a sample to make it valid. :P) (我会发表评论,但显然我的代表不够高,所以我会发布一个带有样本的答案以使其有效。:P)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.