我有一个用折线对象动态制作的图形。它会产生一些有趣的东西,但我想只保留最后10个坐标,一旦到达第10个位置,每个坐标都会向左移动X个像素,新值将在最后添加。
在我的绘图类的Add函数中,我尝试了这种代码:
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
}
}
这不起作用,因为我们无法在ForEach循环中修改集合的变量。在WPF / C#中执行此操作的最佳方法是什么?
我可以这样做:
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);
}
但是我想要一种更清晰的方法来做到这一点,而不必在很短的时间内创建点对象。
答案 0 :(得分:4)
嗯,Point
是一个结构,所以创建新结构的开销应该不错。执行以下操作......
Point p = this.myPolyline.Points[i];
p.X -= 50;
this.myPolyline.Points[i] = p;
......真的没有什么不同,只是因为结构是按值传递的。
考虑到具体情况,您几乎停留在for
循环并重新分配到myPolyline.Points[i]
:
Point
值修改X
。foreach
循环的变量,因此您必须使用for
循环。myPolyline.Points[i].X -= 50
将无效,因为从数组中检索Point
结构,然后不会自动重新分配。 如果您只想移动整个PolyLine
,我可能会建议LayoutTransform
或RenderTransform
,但您移动了Point
的子集s然后将添加其他。
编辑:如果您真的想要重构该操作,可以在PointCollection
上为for
循环创建一个扩展方法,并点这样调整:
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.
}
}
用法:
myPolyline.Points.ChangePoints( new Vector( -50, 0 ) );
您仍然需要以相同的方式更改Point
,但它会在其他地方重构,以便使用更具可读性。 Vector
的使用也使其更具可读性。
答案 1 :(得分:3)
向左移动整个画布,并始终为新点增加插入点。
如果你有大量的项目,这也会提高渲染性能(特别是如果你为动作设置动画)。