动画目标未指定问题 - Silverlight故事板

时间:2011-07-12 11:32:18

标签: silverlight exception animation target storyboard

在这里有一些真正的头疼,因为我似乎无法想到为什么我得到动画目标没有指定错误。我创建了一个静态类,用于抛出大量小火“烧”的故事板。然后,我根据用户的需要创建了许多火灾并为其分配了一个新的故事板,所有这些都在Csharp中。然后我开始故事板,但正如我所说,我一直得到这个错误,我似乎无法理解。这是故事板创建类,当我尝试调用它时。

public static class FireStoryboard
{
    public static Storyboard fireStoryboard(UIElement target)
    {
        Storyboard s = new Storyboard();
        s.RepeatBehavior = RepeatBehavior.Forever;

        DoubleAnimationUsingKeyFrames scaleY = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(scaleY, target);
        scaleY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.ScaleY)"));            
        EasingDoubleKeyFrame e1 = new EasingDoubleKeyFrame();
        e1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        e1.Value = 1.8;
        e1.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        EasingDoubleKeyFrame e2 = new EasingDoubleKeyFrame();
        e2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
        e1.Value = 1;
        e2.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        scaleY.KeyFrames.Add(e1);
        scaleY.KeyFrames.Add(e2);

        DoubleAnimationUsingKeyFrames translateY = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(translateY, target);
        translateY.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateY)"));            
        EasingDoubleKeyFrame e3 = new EasingDoubleKeyFrame();
        e3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        e3.Value = -4;
        e3.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        EasingDoubleKeyFrame e4 = new EasingDoubleKeyFrame();
        e4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
        e4.Value = 0;
        e4.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        translateY.KeyFrames.Add(e3);
        translateY.KeyFrames.Add(e4);

        DoubleAnimationUsingKeyFrames opacity = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(opacity, target);
        opacity.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("UIElement.Opacity"));
        EasingDoubleKeyFrame e5 = new EasingDoubleKeyFrame();
        e5.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
        e5.Value = 0.7;
        EasingDoubleKeyFrame e6 = new EasingDoubleKeyFrame();
        e6.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        e6.Value = 1;
        EasingDoubleKeyFrame e7 = new EasingDoubleKeyFrame();
        e7.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
        e7.Value = 0.7;
        opacity.KeyFrames.Add(e5);
        opacity.KeyFrames.Add(e6);
        opacity.KeyFrames.Add(e7);

        DoubleAnimationUsingKeyFrames shadowDirection = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(shadowDirection, target);
        shadowDirection.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.Direction)"));
        EasingDoubleKeyFrame eShad1 = new EasingDoubleKeyFrame();
        eShad1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
        eShad1.Value = 449;
        EasingDoubleKeyFrame eShad2 = new EasingDoubleKeyFrame();
        eShad2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        eShad2.Value = 449;
        shadowDirection.KeyFrames.Add(eShad1);
        shadowDirection.KeyFrames.Add(eShad2);

        DoubleAnimationUsingKeyFrames shadowDepth = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(shadowDepth, target);
        shadowDirection.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.ShadowDepth)"));          
        EasingDoubleKeyFrame eShad3 = new EasingDoubleKeyFrame();
        eShad3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
        eShad3.Value = 0;
        EasingDoubleKeyFrame eShad4 = new EasingDoubleKeyFrame();
        eShad4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        eShad4.Value = 5;
        EasingDoubleKeyFrame eShad5 = new EasingDoubleKeyFrame();
        eShad5.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
        eShad5.Value = 20;
        shadowDirection.KeyFrames.Add(eShad3);
        shadowDirection.KeyFrames.Add(eShad4);
        shadowDirection.KeyFrames.Add(eShad5);

        DoubleAnimationUsingKeyFrames shadowOpacity = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(shadowOpacity, target);
        shadowDirection.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.Opacity)"));          
        EasingDoubleKeyFrame eShad6 = new EasingDoubleKeyFrame();
        eShad6.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        eShad6.Value = 1;
        EasingDoubleKeyFrame eShad7 = new EasingDoubleKeyFrame();
        eShad7.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
        eShad7.Value = 0;
        shadowDirection.KeyFrames.Add(eShad6);
        shadowDirection.KeyFrames.Add(eShad7);

        DoubleAnimationUsingKeyFrames skewX = new DoubleAnimationUsingKeyFrames();
        Storyboard.SetTarget(skewX, target);
        skewX.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.SkewX)"));           
        EasingDoubleKeyFrame eSkew1 = new EasingDoubleKeyFrame();
        eSkew1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
        eSkew1.Value = 0;
        eSkew1.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        EasingDoubleKeyFrame eSkew2 = new EasingDoubleKeyFrame();
        eSkew2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
        eSkew2.Value = -5;
        eSkew2.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        EasingDoubleKeyFrame eSkew3 = new EasingDoubleKeyFrame();
        eSkew3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1));
        eSkew3.Value = 5;
        eSkew3.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        EasingDoubleKeyFrame eSkew4 = new EasingDoubleKeyFrame();
        eSkew4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1.5));
        eSkew4.Value = -5;
        eSkew4.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        EasingDoubleKeyFrame eSkew5 = new EasingDoubleKeyFrame();
        eSkew5.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(2));
        eSkew5.Value = 0;
        eSkew5.EasingFunction = new BounceEase() { EasingMode = System.Windows.Media.Animation.EasingMode.EaseInOut };
        skewX.KeyFrames.Add(eSkew1);
        skewX.KeyFrames.Add(eSkew2);
        skewX.KeyFrames.Add(eSkew3);
        skewX.KeyFrames.Add(eSkew4);
        skewX.KeyFrames.Add(eSkew5);

        ColorAnimationUsingKeyFrames shadowColor = new ColorAnimationUsingKeyFrames();
        Storyboard.SetTarget(shadowColor, target);
        shadowColor.SetValue(Storyboard.TargetPropertyProperty, new PropertyPath("(UIElement.Effect).(DropShadowEffect.Color)"));            
        EasingColorKeyFrame eColor1 = new EasingColorKeyFrame();
        eColor1.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0));
        eColor1.Value = Colors.Red;
        EasingColorKeyFrame eColor2 = new EasingColorKeyFrame();
        eColor2.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.5));
        eColor2.Value = Color.FromArgb(255, 254, 31, 0);
        EasingColorKeyFrame eColor3 = new EasingColorKeyFrame();
        eColor3.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.7));
        eColor3.Value = Color.FromArgb(255, 254, 255, 0);
        EasingColorKeyFrame eColor4 = new EasingColorKeyFrame();
        eColor4.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0.8));
        eColor4.Value = Colors.Black;
        shadowColor.KeyFrames.Add(eColor1);
        shadowColor.KeyFrames.Add(eColor2);
        shadowColor.KeyFrames.Add(eColor3);
        shadowColor.KeyFrames.Add(eColor4);

        s.Children.Add(scaleY);
        s.Children.Add(translateY);
        s.Children.Add(opacity);
        s.Children.Add(shadowDirection);
        s.Children.Add(shadowDepth);
        s.Children.Add(shadowOpacity);
        s.Children.Add(skewX);
        s.Children.Add(shadowColor);


        Storyboard.SetTarget(s, target);
        return s;
    }
}

以下是我将其分配给每个火灾图像的地方:

Storyboard fireStoryboard = FireStoryboard.fireStoryboard(fire);
        fireStoryboard.Begin();

非常感谢任何帮助。我错过了在某处设定目标吗?我真的看不到:(。

1 个答案:

答案 0 :(得分:1)

当elementName x:Name可以在其资源中包含Storyboard的元素中找到时,以下工作正常。实现MVVM时,您还可以动态设置名称,因为这样您大多数时候都不需要x:Name。请参阅以下内容;

    private void GoShowUpElement(FrameworkElement element, double opacity)
    {
        if (element != null)
        {
            string guidString = Guid.NewGuid().ToString();
            element.SetValue(NameProperty, guidString);//  When you don't use x:Name in Xaml  (with MVVM normally not nessasary)

            if (!this.LayoutRoot.Resources.Contains(guidString))
            {
                this.LayoutRoot.Resources.Add(guidString, ShowUpElement(opacity, 1000, guidString)); // when you do use x:Name replace guidString with the x:Name you used.
                Storyboard simultaniousStoryboard = this.LayoutRoot.Resources[guidString] as Storyboard;
                simultaniousStoryboard.Completed += new EventHandler(simultaniousStoryboard_Completed);
                simultaniousStoryboard.Begin();
            }
        }
    }

当故事板完成时,我会清理资源,这会在使用越来越多的故事板时显着提高性能;)

    private void simultaniousStoryboard_Completed(object sender, EventArgs e)
    {
        Storyboard storyboard = sender as Storyboard;
        foreach (DictionaryEntry dictionaryEntry in this.LayoutRoot.Resources)
        {
            Storyboard resourceStoryboard = dictionaryEntry.Value as Storyboard;
            if (resourceStoryboard != null)
            {
                if (resourceStoryboard.GetValue(NameProperty) == storyboard.GetValue(NameProperty))
                    this.LayoutRoot.Resources.Remove(dictionaryEntry.Key);
            }
        }
    }

以下是为我创建可重用故事板的静态方法。

    public static Storyboard ShowUpElement(double opacity, int milliseconds, string elementName)
    {
        Storyboard storyboard = new Storyboard();
        storyboard.Children.Add(StoryboardBasic.KeyFramedAnimation(opacity, 0.9, 0, milliseconds, elementName, "Opacity"));
        //storyboard.Children.Add(StoryboardBasic.KeyFramedAnimation....  Add more if you want
        return storyboard;
    }

DoubleAnimationUsingKeyFrames也可以是其他类型的动画。

    public static DoubleAnimationUsingKeyFrames KeyFramedAnimation(double fromValue, double toValue, int startMilliSeconds, int endMilliseconds, string targetElementName, PropertyPath propertyPath)
    {
        List<SplineDoubleKeyFrame> splineDoubleKeyFrames = new List<SplineDoubleKeyFrame>()
            {
                new SplineDoubleKeyFrame() { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(startMilliSeconds)), Value = fromValue, KeySpline = new KeySpline() { ControlPoint1 = new Point(0,0), ControlPoint2= new Point(1,0)} },
                new SplineDoubleKeyFrame() { KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(endMilliseconds)), Value = toValue, KeySpline = new KeySpline() { ControlPoint1 = new Point(0,0), ControlPoint2= new Point(0,1)} },
            };

        DoubleAnimationUsingKeyFrames animation = new DoubleAnimationUsingKeyFrames();
        foreach (SplineDoubleKeyFrame linearDoubleKeyFrame in splineDoubleKeyFrames)
            animation.KeyFrames.Add(linearDoubleKeyFrame);

        Storyboard.SetTargetName(animation, targetElementName);
        Storyboard.SetTargetProperty(animation, propertyPath);

        return animation;
    }

如果这有用,请告诉我,提前致谢。