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.

Foi útil?

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:

  1. Você tem que modificar o Point com um diferente X valor.
  2. Você não pode modificar a variável de um foreach loop, então você tem que usar um for ciclo.
  3. myPolyline.Points[i].X -= 50 não vai funcionar por causa da maneira como Point 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 PointS 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 Pointestá 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).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top