C# 为什么我能';是否使用DoubleAnimationUsingPath设置TranslateForm.X属性的动画?

C# 为什么我能';是否使用DoubleAnimationUsingPath设置TranslateForm.X属性的动画?,c#,wpf,animation,bezier,C#,Wpf,Animation,Bezier,我在wpf中创建了一个自定义的面板,在那里,渲染后需要为孩子们设置动画。我想要为每个孩子制作的动画是使用贝塞尔曲线进行平移(移动) 我遵循并创建了AddAnimation方法,在该方法中,我添加了路径,我希望在该路径中为面板的每个项目设置动画 不幸的是,我得到了以下例外: 无法对对象上的“X”属性设置动画 使用 'System.Windows.Media.Animation.DoubleAnimationUsingPath' 但是,如果没有使用路径的双重动画,我该如何设置X属性的动画呢 以下是该

我在wpf中创建了一个自定义的
面板
,在那里,渲染后需要为孩子们设置动画。我想要为每个孩子制作的动画是使用贝塞尔曲线进行平移(移动)

我遵循并创建了
AddAnimation
方法,在该方法中,我添加了
路径
,我希望在该路径中为面板的每个项目设置动画

不幸的是,我得到了以下例外:

无法对对象上的“X”属性设置动画 使用 'System.Windows.Media.Animation.DoubleAnimationUsingPath'

但是,如果没有使用路径的
双重动画,我该如何设置X属性的动画呢

以下是该方法:

private void AddAnimation(FrameworkElement子元素,Point子元素位置)
{
var middlePoint=GetMiddlePoint();
var finalPoint=GetFinalPoint();
var animatedTranslateTransform=新的TranslateTransform();
child.RenderTransform=动画TranslateTransform;
child.renderTransferMorigin=新点(0.5,0.5);
//创建动画路径。
PathGeometry animationPath=新建PathGeometry();
PathFigure pFigure=新的PathFigure();
pFigure.StartPoint=子位置;
PolyBezierSegment pBezierSegment=新的PolyBezierSegment();
pBezierSegment.Points.Add(中点);
pBezierSegment.Points.Add(finalPoint);
pFigure.Segments.Add(pBezierSegments);
animationPath.Figures.Add(pFigure);
//冻结PathGeometry以获得性能优势。
animationPath.Freeze();
//使用路径创建双动画以移动
//通过设置动画沿路径水平放置矩形
//它的翻译形式。
双重动画使用路径平移动画=
使用路径()创建新的双动画;
translateAnimation.PathGeometry=动画路径;
TranslateAnimation.Duration=TimeSpan.FromSeconds(5);
//将Source属性设置为X。这将使
//动画将从中生成水平偏移值
//路径信息。
translateAnimation.Source=PathAnimationSource.X;
//将动画设定为以X特性为目标
故事板.SetTarget(translateAnimation,child);
Storyboard.SetTargetProperty(TranslateAnimation,
新的PropertyPath(((FrameworkElement.RenderTransform)。(TranslateTransform.X));
//使用路径创建双动画以移动
//通过设置动画沿路径垂直放置矩形
//它的翻译形式。
双重动画使用路径平移动画=
使用路径()创建新的双动画;
translateYAnimation.PathGeometry=动画路径;
translateYAnimation.Duration=TimeSpan.FromSeconds(5);
//将源属性设置为Y。这将使
//动画将从中生成垂直偏移值
//路径信息。
translateYAnimation.Source=PathAnimationSource.Y;
//将动画设置为以Y特性为目标
//名为“AnimatedTranslateTransform”的TranslateTransform。
故事板.SetTarget(translateYAnimation,child);
Storyboard.SetTargetProperty(translateYAnimation,
新的PropertyPath(“(FrameworkElement.RenderTransform)。(TranslateTransform.Y)”);
//创建故事板以包含和应用动画。
情节提要路径animationstoryboard=新建情节提要();
pathAnimationStoryboard.RepeatBehavior=RepeatBehavior.Forever;
pathAnimationStoryboard.Children.Add(TranslateAnimation);
pathAnimationStoryboard.Children.Add(translateYAnimation);
//加载矩形时启动动画。
已加载的子项+=(发件人,参数)=>
{
Debug.WriteLine($“Child{Child}加载”);
pathAnimationStoryboard.Begin(子级);
};
}

查看AnimationException的
InnerException
属性

出现异常的原因是,对于
PolyBezierSegment
,两个点不够,因为它需要两个控制点和一个端点,因此每条曲线需要三个点

改为使用
多方Bezier段

var pBezierSegment = new PolyQuadraticBezierSegment();
pBezierSegment.Points.Add(middlePoint);
pBezierSegment.Points.Add(finalPoint);
或者只是一个
方形Bezier段

var bezierSegment = new QuadraticBezierSegment();
bezierSegment.Point1 = middlePoint;
bezierSegment.Point2 = finalPoint;

代码对于它应该做的事情来说似乎太复杂了。您可以将情节提要替换为两个
Double AnimationUsingPath
子级,并使用一个
MatrixAnimationUsingPath
MatrixTransform的
矩阵
属性设置动画:

var animation = new MatrixAnimationUsingPath
{
    PathGeometry = animationPath,
    Duration = TimeSpan.FromSeconds(5)
};

var transform = new MatrixTransform();

child.RenderTransform = transform;
child.Loaded += (s, e) =>
    transform.BeginAnimation(MatrixTransform.MatrixProperty, animation);

查看AnimationException的
InnerException
属性

出现异常的原因是,对于
PolyBezierSegment
,两个点不够,因为它需要两个控制点和一个端点,因此每条曲线需要三个点

改为使用
多方Bezier段

var pBezierSegment = new PolyQuadraticBezierSegment();
pBezierSegment.Points.Add(middlePoint);
pBezierSegment.Points.Add(finalPoint);
或者只是一个
方形Bezier段

var bezierSegment = new QuadraticBezierSegment();
bezierSegment.Point1 = middlePoint;
bezierSegment.Point2 = finalPoint;

代码对于它应该做的事情来说似乎太复杂了。您可以将情节提要替换为两个
Double AnimationUsingPath
子级,并使用一个
MatrixAnimationUsingPath
MatrixTransform的
矩阵
属性设置动画:

var animation = new MatrixAnimationUsingPath
{
    PathGeometry = animationPath,
    Duration = TimeSpan.FromSeconds(5)
};

var transform = new MatrixTransform();

child.RenderTransform = transform;
child.Loaded += (s, e) =>
    transform.BeginAnimation(MatrixTransform.MatrixProperty, animation);

关于如何显著简化代码,请参见编辑后的答案。谢谢@Clemens。所以矩阵的第一行是
X
点,第二行是
Y
?我花了太多时间搜索一个依赖属性,它暴露了一个
,但它看起来像