2010-03-04 11 views
22

En C# WinForms: estoy dibujando un gráfico de líneas en tiempo real que se basa en los datos recibidos a través del puerto en serie cada 500 ms.Formulario de fuerza para redibujar?

La lógica e.Graphics.DrawLine está dentro del controlador OnPaint del formulario.

Una vez que recibo los datos del puerto serie, necesito llamar a algo que hace que el formulario se vuelva a dibujar para que se invoque el controlador OnPaint. He intentado esto. Renovar y esto. Invalidar, y lo que sucede es que pierdo lo que se había dibujado anteriormente en el formulario.

¿Hay alguna otra forma de lograr esto sin perder lo que se ha dibujado en su formulario?

Respuesta

20

El punto es que debes pensar en almacenar tus datos de dibujo en alguna parte. Como ya se dijo, un mapa de bits de buffer es una solución. Sin embargo, si no tiene demasiado para dibujar, a veces es más fácil y mejor almacenar sus datos de dibujo en una variable o una matriz y volver a dibujar todo en el evento OnPaint.

Supongamos que recibe algunos datos de punto que se deben agregar al gráfico. Abetos de todo lo que crea una lista de puntos:

List<Point> points = new List<Point>(); 

Entonces cada vez que reciba un nuevo punto de añadirlo a la lista y actualizar la forma:

points.Add(newPoint); 
this.Refresh(); 

En el caso OnPaint poner el siguiente código :

private void Form_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.DrawLines(Pens.Red, points); 
} 

Esto funciona bastante rápido hasta de alguna manera 100 000 puntos y utiliza mucha menos memoria que la solución de mapa de bits del búfer. Pero debe decidir qué camino usar según la complejidad del dibujo.

+0

Gracias - funciona bien. Pregunta rápida - Estoy dibujando este gráfico de líneas en tiempo real - eventualmente voy a exceder el ancho máximo disponible en la pantalla, por lo que querré que las líneas que he dibujado en el formulario se desplacen ligeramente hacia la izquierda, a hacer espacio para las nuevas coordenadas que se trazan. ¿Alguna sugerencia sobre cómo hacer esto? Básicamente estoy desarrollando una aplicación de tipo EKG simple. – Chris

+2

Hay muchas formas de hacerlo. Por ejemplo, puede usar e.Graphics.TranslateTransform (-x, 0); Esto hace que todos sus gráficos sean dibujados desplazados a la izquierda por x píxeles. – Zenya

0

la forma predeterminada de manejar esto es crear un mapa de bits de memoria y dibujar sobre eso luego establecer la propiedad de la imagen del cuadro de imagen en el mapa de bits de memoria.

5

Como dijo rerun, necesita almacenar en búfer su formulario (ya que parece que está descartando los datos después de dibujarlo).

Esta es básicamente la forma en que lo haría:

private Bitmap buffer; 

// When drawing the data: 
if (this.buffer == null) 
{ 
    this.buffer = new Bitmap(this.ClientSize.Width, this.ClientSize.Height); 
} 

// then draw on buffer 
// then refresh the form 
this.Refresh(); 

protected override void OnPaint(PaintEventArgs e) 
{ 
    if (this.buffer != null) 
    { 
     e.Graphics.DrawImage(this.buffer); 
    } 
} 

Dicho esto, es probable que quiere almacenar sus datos para que pueda cambiar el tamaño del búfer cuando y los cambios de tamaño de formulario y luego vuelven a dibujar los datos antiguos en eso.

0

Necesitará almacenar datos históricos en algún lugar y simplemente volver a pintarlos.

Eso será mucho más fácil que decir almacenar en caché y recortar mapas de bits.

1

La solución puede ser this.Invalidate()

Cuestiones relacionadas