How to Move an Ellipse Along a Path in WPF Code-Behind

60 Views Asked by At

I'm trying to move an ellipse along a simple PathGeometry in code-behind. The ellipse shows up. The path shows up. Nothing moves. What am I missing? Thanks!

Here's what I have. SchematicDiagram is a Canvas. sData contains a Path. Code is in VB.

                    OrPath = New Path
                    OrPath.Stroke = HGLBrush
                    OrPath.StrokeThickness = 1
                    OrPath.Data = Geometry.Parse(sData)

                    'Add to PathGeometry named flowPathGeometry
                    FlowPathGeometry = New PathGeometry
                    FlowPathGeometry.AddGeometry(OrPath.Data)
                    FlowPathGeometry.Freeze()

                    SchematicDiagram.Children.Add(OrPath)

                    'Now animate ------------------------------------------------------

                    'Create the Ellipse to animate.

                    Dim shapeMatrixTransform As New MatrixTransform()

                    Dim newellipse As New Ellipse
                    newellipse.Name = "FlowPathCircle"
                    newellipse.Fill = Brushes.Blue
                    newellipse.Height = 5
                    newellipse.Width = 5
                    newellipse.RenderTransform = shapeMatrixTransform
                    SchematicDiagram.Children.Add(newellipse)

                    NameScope.SetNameScope(SchematicDiagram, New NameScope())
                    SchematicDiagram.RegisterName("shapeMatrixTransform", newellipse)

                    'Create a MatrixAnimationUsingPath to move the shape along the path by animating its MatrixTransform
                    Dim ma As New Animation.MatrixAnimationUsingPath()
                    ma.Duration = TimeSpan.FromSeconds(5)
                    ma.RepeatBehavior = Media.Animation.RepeatBehavior.Forever
                    ma.PathGeometry = FlowPathGeometry 'the path "geometry" To use

                    'Set the animation to target the Matrix property
                    'of the MatrixTransform named "shapeMatrixTransform".
                    Media.Animation.Storyboard.SetTargetName(ma, "shapeMatrixTransform")
                    Media.Animation.Storyboard.SetTargetProperty(ma, New PropertyPath(MatrixTransform.MatrixProperty))

                    'Create a Storyboard to contain and apply the animation
                    Dim pathAnimationStoryboard As New Animation.Storyboard
                    pathAnimationStoryboard.Children.Add(ma)

                    'To Start the storyboard.
                    pathAnimationStoryboard.Begin(SchematicDiagram)

'Nothing Happens in the canvas after this code executes

1

There are 1 best solutions below

1
Clemens On BEST ANSWER

You do not need the Storyboard. Just call

shapeMatrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, ma)

Here is a compact version of your code in C#. Besides that it does not use a Storyboard, it also uses a Path with an EllipseGeometry instead of an Ellipse, because the Path is centered while the Ellipse is top/left aligned.

var path = new Path
{
    Stroke = HGLBrush,
    StrokeThickness = 1,
    Data = Geometry.Parse(sData)
};

var flowPathGeometry = new PathGeometry();
flowPathGeometry.AddGeometry(path.Data);
flowPathGeometry.Freeze();

SchematicDiagram.Children.Add(path);

var shapeMatrixTransform = new MatrixTransform();

var ellipse = new Path
{
    Data = new EllipseGeometry(new Point(), 2.5, 2.5),
    Fill = Brushes.Blue,
    RenderTransform = shapeMatrixTransform
};

SchematicDiagram.Children.Add(ellipse);

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

shapeMatrixTransform.BeginAnimation(MatrixTransform.MatrixProperty, animation);

For completeness it seems also worth mentioning that instead of the RenderTransform of the ellipse Path you may as well animate the Transform property of its geometry:

var ellipse = new Path
{
    Data = new EllipseGeometry(new Point(), 2.5, 2.5)
    {
        Transform = shapeMatrixTransform
    },
    Fill = Brushes.Blue
};