Цель анимации не указана - раскадровки Silverlight
Здесь происходит настоящая царапина, потому что я не могу понять, почему я получаю цель анимации, не указавшую ошибку. Я создаю статический класс для раздачи раскадровок множества маленьких "горящих" огней. Затем я создаю столько пожаров, сколько захочет пользователь, и назначаю ему новую раскадровку, все в 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 ответ
Следующее прекрасно работает для меня, когда elementName x:Name можно найти в элементе, у которого есть раскадровка в его ресурсах. При реализации 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;
}
Дайте мне знать, если это было полезно, спасибо заранее.