Я создал простой подкласс StackPanel
то, что я могу переместиться на экране с помощью анимированного TranslateTransform
. Это похоже на это:
public class MovingStackPanel : StackPanel
{
public void BeginMove(Point translatePosition)
{
RenderTransform = new TranslateTransform();
Duration d = new Duration(new TimeSpan(0, 0, 0, 0, 400));
DoubleAnimation x = new DoubleAnimation(translatePosition.X, d);
DoubleAnimation y = new DoubleAnimation(translatePosition.Y, d);
/*
Storyboard.SetTarget(x, RenderTransform);
Storyboard.SetTargetProperty(x, new PropertyPath("X"));
Storyboard.SetTarget(y, RenderTransform);
Storyboard.SetTargetProperty(y, new PropertyPath("Y"));
Storyboard sb = new Storyboard();
sb.Children.Add(x);
sb.Children.Add(y);
sb.Completed += sb_Completed;
sb.Begin();
*/
RenderTransform.BeginAnimation(TranslateTransform.XProperty, x);
RenderTransform.BeginAnimation(TranslateTransform.YProperty, y);
}
void sb_Completed(object sender, EventArgs e)
{
Console.WriteLine("Completed.");
}
}
И вот моя проблема: Если я анимирую свойства X and Y непосредственно, как код выше делает, он работает. Но если я использую прокомментированный код выше его, который является действительно самым простым созданием a Storyboard
в вообразимом коде ничего не происходит. Выполнения анимации - по крайней мере, событие Completed генерируется - но ничто не изменяется на экране.
Очевидно я делаю что-то не так, но я не вижу, каково это. Каждый пример создания раскадровок в коде я видел взгляды точно так же, как это. Существует, очевидно, что-то об анимациях и раскадровках, которые я еще не знаю: что это?
Как оказалось, вы не можете использовать синтаксис пути к свойствам в этом случае, потому что анимируемые свойства не являются свойствами FrameworkElement
. По крайней мере, так я интерпретирую удивительно сбивающее с толку исключение, которое я получаю, когда вношу изменение, предложенное Анвакой:
Cannot automatically create animation clone for frozen property values on
'System.Windows.Media.TranslateTransform' objects. Only FrameworkElement and
FrameworkContentElement (or derived) types are supported.
Кажется, чтобы оживить их, я должен использовать NameScope
и использовать SetTargetName
, чтобы назвать TransformElement
. Затем, пока я передаю FrameworkElement
, который задаю область видимости имени методу Begin
, раскадровка может найти объект и свойства и анимировать их, и все это работает. Конечный результат выглядит следующим образом:
public void BeginMove(Point translatePosition)
{
NameScope.SetNameScope(this, new NameScope());
RenderTransform = new TranslateTransform();
RegisterName("TranslateTransform", RenderTransform);
Duration d = new Duration(new TimeSpan(0, 0, 0, 0, 400));
DoubleAnimation x = new DoubleAnimation(translatePosition.X, d);
DoubleAnimation y = new DoubleAnimation(translatePosition.Y, d);
Storyboard.SetTargetName(x, "TranslateTransform");
Storyboard.SetTargetProperty(x, new PropertyPath(TranslateTransform.XProperty));
Storyboard.SetTargetName(y, "TranslateTransform");
Storyboard.SetTargetProperty(y, new PropertyPath(TranslateTransform.YProperty));
Storyboard sb = new Storyboard();
sb.Children.Add(x);
sb.Children.Add(y);
sb.Completed += sb_Completed;
// you must pass this to the Begin method, otherwise the timeline won't be
// able to find the named objects it's animating because it doesn't know
// what name scope to look in
sb.Begin(this);
}
Это синтаксис пути к свойству . Работает следующий подход:
public void BeginMove(Point translatePosition)
{
RenderTransform = new TranslateTransform();
Duration d = new Duration(new TimeSpan(0, 0, 0, 0, 400));
DoubleAnimation x = new DoubleAnimation(translatePosition.X, d);
DoubleAnimation y = new DoubleAnimation(translatePosition.Y, d);
Storyboard.SetTarget(x, this);
Storyboard.SetTargetProperty(x,
new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.X)"));
Storyboard.SetTarget(y, this);
Storyboard.SetTargetProperty(y,
new PropertyPath("(UIElement.RenderTransform).(TranslateTransform.Y)"));
Storyboard sb = new Storyboard();
sb.Children.Add(x);
sb.Children.Add(y);
sb.Completed += sb_Completed;
sb.Begin();
//RenderTransform.BeginAnimation(TranslateTransform.XProperty, x);
//RenderTransform.BeginAnimation(TranslateTransform.YProperty, y);
}