I have a graphic made dynamically with a polyline object. It produces something interesting but I would like to keep only the last 10 coordinates and once we have reach the 10th position, every coordinate would move to the left by X pixel and the new value will be added at the end.
In the Add function of my drawing class I tried this kind of code:
if (points.Count > 10)
{
myPolyline.Points.RemoveAt(0);
foreach(Point p in myPolyline.Points)
{
p.X = p.X - 50;//Move all coord back to have a place for the new one
}
}
That doesn't work because we cannot modify a variable of the collection in a ForEach loop. What is the best way to do this in WPF/C#?
I can do it by doing this:
for (int i = 0; i < this.myPolyline.Points.Count; i++)
{
this.myPolyline.Points[i] = new Point(this.myPolyline.Points[i].X - 50, this.myPolyline.Points[i].Y);
}
But I would like a cleaner way to do it without having to create point object very time.
Well, the Point
is a struct, so the overhead of creating new ones shouldn't be bad. Doing the following...
Point p = this.myPolyline.Points[i];
p.X -= 50;
this.myPolyline.Points[i] = p;
...would really be no different, simply because structs are passed around by value.
You are pretty much stuck with a for
loop and reassigning to myPolyline.Points[i]
, considering the circumstances:
Point
with a different X
value.foreach
loop, so you have to use a for
loop.myPolyline.Points[i].X -= 50
won't work because of the way the Point
struct is retrieved from the array and then not re-assigned automatically.If you simply wanted to move the whole PolyLine
, I might have suggested a LayoutTransform
or RenderTransform
, but you're moving a subset of Point
s and then will add others.
Edit: If you really want to refactor that operation, you could create an extension method on PointCollection
for the for
loop and point tweaking like this:
static public void ChangePoints( this PointCollection pc, Vector v ) {
for (int i = 0; i < pc.Count; i++ ) {
pc[i] += v;
// the above works on the indexer because you're doing an operation on the
// Point rather than on one of the Point's members.
}
}
Usage:
myPolyline.Points.ChangePoints( new Vector( -50, 0 ) );
You still have to change the Point
s in the same way, but it's refactored elsewhere so that the usage is more readable. And usage of Vector
makes it more readable, too.