Wpf 为什么不';当我';我在用故事板?

Wpf 为什么不';当我';我在用故事板?,wpf,animation,storyboard,Wpf,Animation,Storyboard,我创建了一个简单的StackPanel子类,可以使用动画TranslateTransform在屏幕上移动。看起来是这样的: public class MovingStackPanel : StackPanel { public void BeginMove(Point translatePosition) { RenderTransform = new TranslateTransform(); Duration d = new Duration(

我创建了一个简单的
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.");
    }
} 
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);

}
这是我的问题:如果我像上面的代码那样直接设置X和Y属性的动画,它就会工作。但是如果我在上面使用注释掉的代码,这是可以想象得到的最简单的
故事板的创建,那么什么也不会发生。动画运行-至少,已完成的事件被引发-但屏幕上没有任何变化

很明显我做错了什么,但我看不出是什么。我见过的每一个用代码创建故事板的例子都是这样的。很明显,关于动画和故事板,我还不知道一些东西:它是什么?

它的语法。以下方法有效:

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);
}

事实证明,在这种情况下不能使用属性路径语法,因为正在设置动画的属性不是
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.
要使这些元素具有动画效果,我似乎必须使用
名称范围
,并使用
SetTargetName
来命名
TransformElement
。然后,只要我将我设置名称范围的
FrameworkElement
传递给
Begin
方法,故事板就可以找到对象和属性并设置它们的动画,一切都可以正常工作。最终结果如下所示:

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.");
    }
} 
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);

}

仅供参考-我在Microsoft Connect上发布了此错误。看见也很有帮助。