title: Dynamically modifying a Path, Geometry, Shape in XAML
body: <p>I am stuck.  I want to do some sophisticated animations in XAML, in which the geometry of the image gets modified at runtime.  I want to start out simple, and then make something far more interesting, but nothing seems to work.
  For now, all I want to do is draw an arc on the screen using a for-loop, and this arc will be modified by a slider.  The slider will control the starting point of the arc.  So, if I have the slider at Pi/4, it will draw an arc from Pi/4 to 2Pi.</p>
  <p>I've tried so many different ways. Right now I've created a class of the type <code>Shape</code>, and tried to modify the <code>DefiningGeometry</code> which is a property of the <code>Shape</code> class.  The <code>startRadians</code> gets modified by the slider, so that part works OK, I got the binding to work.  But, after <code>startRadians</code> gets changed (it is a <code>DependencyProperty</code>, btw) I want the class to re-calculate the geometry of the circle.  (Like a cherry pie that is missing a bigger piece  as <code>startRadians</code> gets changed.)  The real problem is that <code>DefiningGeometry</code> is a read-only property, so I can't change it on the fly.  (Am I right about this?)  Even if I could, I don't know the way to write the line of code so that <code>DrawMyArc</code> fires again, and the results get reloaded into <code>DefiningGeometry</code>.</p>
  <p>OK, so I need some guidance.  Should I change the parent class, so that I have an easily modifiable Path/geometry?  I am at a loss here.</p>
  <p>Should I use an entirely different approach, like where you dynamically make/delete the geometry using StreamGeometry?</p>
  <p>Here's the relevant code:</p>
  <pre class="lang-cs prettyprint-override"><code>using System;
  using System.Collections.Generic;
  using System.Windows;
  using System.Windows.Media;
  using System.Windows.Shapes;
  
  
  namespace January14noon
  {
      public class myCircle : Shape
      {
  
          public double startRadians
          {
              get { return (double)GetValue(startRadiansProperty); }
              set { SetValue(startRadiansProperty, value); }
          }
  
          protected override Geometry DefiningGeometry
          {
              get
              {
                  return DrawMyArc(100, 200, true, 40, 40, 360, startRadians, 2 * Math.PI);
              }
          }
          // Using a DependencyProperty as the backing store for startRadians.  This enables animation, styling, binding, etc...
          public static readonly DependencyProperty startRadiansProperty =
              DependencyProperty.Register(&quot;startRadians&quot;, typeof(double), typeof(myCircle), new PropertyMetadata(Math.PI / 4, new PropertyChangedCallback(startRadians_PropertyChanged)));
  
          private static void startRadians_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              //
              //    
          }
          public PathGeometry DrawMyArc(double centX, double centY, bool CW, double radiusX, double radiusY, int numberOfSegs, double startRad, double endRad)
          {
              double[,] rawPoints = new double[numberOfSegs, 2];
              List&lt;LineSegment&gt; segments = new List&lt;LineSegment&gt;();
              double arcLength;
  
              
                  arcLength = endRad - startRad;
                  for (int i = 0; i &lt; numberOfSegs; i++)
                  {
                      rawPoints[i, 0] = radiusX * Math.Sin(i * (arcLength / numberOfSegs) + startRad) + centX;
                      rawPoints[i, 1] = radiusY * -Math.Cos(i * (arcLength / numberOfSegs) + startRad) + centY;
  
                      segments.Add(new LineSegment(new Point(rawPoints[i, 0], rawPoints[i, 1]), true));
                  }
              
              LineSegment[] segArray = segments.ToArray();
              PathFigure figure = new PathFigure(new Point(centX, centY), segments, false);
              PathGeometry myGeometry = new PathGeometry();
              myGeometry.Figures.Add(figure);
              return myGeometry;
          }
      }
  }
  </code></pre>
  <p>And XAML:</p>
  <pre class="lang-xml prettyprint-override"><code>&lt;Window x:Class=&quot;January14noon.MainWindow&quot;
      xmlns=&quot;http://schemas.microsoft.com/winfx/2006/xaml/presentation&quot;
      xmlns:x=&quot;http://schemas.microsoft.com/winfx/2006/xaml&quot;
      xmlns:d=&quot;http://schemas.microsoft.com/expression/blend/2008&quot;
      xmlns:mc=&quot;http://schemas.openxmlformats.org/markup-compatibility/2006&quot;
      xmlns:local=&quot;clr-namespace:January14noon&quot;
      mc:Ignorable=&quot;d&quot;
          
      Title=&quot;MainWindow&quot; Height=&quot;350&quot; Width=&quot;525&quot;&gt;
      &lt;Window.Resources&gt;
          &lt;local:myCircle x:Key=&quot;myCircleDataSource&quot; d:IsDataSource=&quot;True&quot;/&gt;
      &lt;/Window.Resources&gt;
      &lt;Grid DataContext=&quot;{Binding Source={StaticResource myCircleDataSource}}&quot;&gt;
          &lt;Slider x:Name=&quot;slider&quot; VerticalAlignment=&quot;Top&quot; Margin=&quot;0,0,163.898,0&quot; Value=&quot;{Binding startRadians, Mode=OneWayToSource}&quot;/&gt;
          &lt;TextBox x:Name=&quot;myTextBox&quot; HorizontalAlignment=&quot;Right&quot; Height=&quot;23&quot; TextWrapping=&quot;Wrap&quot; Text=&quot;{Binding startRadians}&quot; VerticalAlignment=&quot;Top&quot; Width=&quot;147.797&quot;/&gt;
          &lt;!--&lt;local:myCircle x:Name=&quot;instanceOfCircle&quot; /&gt;--&gt;
          &lt;local:myCircle Stroke=&quot;Black&quot; StrokeThickness=&quot;2&quot;/&gt;
      &lt;/Grid&gt;
  &lt;/Window&gt;
  </code></pre>
  <p>Any help would be appreciated.  Just general approach, something specific even words of encouragement.</p>
  <p>TYIA</p>