Como mover toda a coordenada de um objeto WPF Polyline?
Pergunta
Eu tenho um gráfico feito dinamicamente com um objeto Polyline. Ele produz algo interessante, mas eu gostaria de manter apenas as últimas 10 coordenadas e, quando chegarmos à 10ª posição, todas as coordenadas se moveriam para a esquerda por x pixel e o novo valor será adicionado no final.
Na função ADD da minha aula de desenho, tentei esse tipo de código:
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
}
}
Isso não funciona porque não podemos modificar uma variável da coleção em um loop foreach. Qual é a melhor maneira de fazer isso no WPF/C#?
Mais informações
Eu posso fazer isso fazendo isso:
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);
}
Mas eu gostaria de uma maneira mais limpa de fazê -lo sem ter que criar um objeto de ponto muito tempo.
Solução
Bem o Point
é uma estrutura, então a sobrecarga de criar novos não deve ser ruim. Fazendo o seguinte ...
Point p = this.myPolyline.Points[i];
p.X -= 50;
this.myPolyline.Points[i] = p;
... realmente não seria diferente, simplesmente porque as estruturas são transmitidas pelo valor.
Você está praticamente preso com um for
loop e reatribuição a myPolyline.Points[i]
, considerando as circunstâncias:
- Você tem que modificar o
Point
com um diferenteX
valor. - Você não pode modificar a variável de um
foreach
loop, então você tem que usar umfor
ciclo. myPolyline.Points[i].X -= 50
não vai funcionar por causa da maneira comoPoint
A estrutura é recuperada da matriz e não assinada automaticamente.
Se você simplesmente quisesse mover o todo PolyLine
, Eu poderia ter sugerido um LayoutTransform
ou RenderTransform
, mas você está movendo um subconjunto de Point
S e então adicionará outros.
Editar: Se você realmente deseja refatorar essa operação, pode criar um método de extensão em PointCollection
para o for
loop e aprimoramento do ponto assim:
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.
}
}
Uso:
myPolyline.Points.ChangePoints( new Vector( -50, 0 ) );
Você ainda tem que mudar o Point
está da mesma maneira, mas é refaturado em outros lugares para que o uso seja mais legível. E uso de Vector
Torna mais legível também.
Outras dicas
Mova a tela inteira que restava e aumente o ponto de inserção para os novos pontos o tempo todo.
Se você tiver toneladas de itens, isso também melhorará o desempenho da renderização (especialmente se você animar o movimento).