从代码隐藏动态访问故事板?

时间:2012-11-10 02:42:45

标签: c# silverlight storyboard windows-phone

我正在使用Windows Phone应用,但我相信这也适用于Silverlight。我想创建一个Storyboard(现在我在我的代码隐藏页面中将其创建为全局变量以进行测试),将Rectangle的{​​{1}}属性从透明更改为红色,然后回到透明。我将在多个矩形中重复使用此Fill,因此我希望能够从代码隐藏中访问它并Storyboard。我找不到这样的例子,所以我用我认为可行的方法给了它一个镜头。

初始设置:

Begin()

然后,在任何时候,如果我有一个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 实例,它将位于Rectangle上方,我想启动故事板 - 这将转变为{{1} }红色,然后回到透明:

Canvas

但是,它会在Rectangle行引发以下异常:

  

用户代码未处理InvalidOperationException异常   类型'System.InvalidOperationException'发生在   System.Windows.ni.dll但未在用户代码中处理

我希望我的想法不会太远,但也许有一种更简单的方法?如果没有,谁能看到我做错了什么?

更新(解决方案):

我按照@Josh Mackey提供的示例将我的// Set the target to my current rectangle, and begin: Storyboard.SetTarget(turnOn, myRectangle); Storyboard.SetTarget(turnOn, myRectangle); sb.Begin(); 移到了sb.Begin()页面,我认为无论如何它都会更干净。我之前没有注意到的是异常细节,声明“ColorAnimation不能用于动画属性Fill由于不兼容的类型。”我能够通过改变我的{{1来使用@Josh Mackey的解决方案到Storyboard。新代码:

XAML

我只能使用一个动画因为我能够将ColorAnimation设置为ColorAnimationUsingKeyFrames而我找到了 this article ,其中描述了我如何访问<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> 在我的代码隐藏中就像这样:

AutoReverse

现在它按预期工作了!

1 个答案:

答案 0 :(得分:5)

您无法在XAML文件中定义故事板的任何特殊原因?

以下示例来自我的WP7项目。它是一个用户控件,但是同样的过程适用,只需将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>

使用它:

Storyboard storyBoard = (Storyboard)this.Resources["aniFlipToBack"];
storyBoard.Begin();

(我会评论,但显然我的代表不够高,所以我会发一个样本的答案,使其有效。:P)