2010-03-04 20 views
22

In C# WinForms - Sto disegnando un grafico a linee in tempo reale basato su dati ricevuti tramite porta seriale ogni 500 ms.Forza modulo da ridisegnare?

La logica e.Graphics.DrawLine è all'interno del gestore OnPaint del modulo.

Una volta ricevuti i dati dalla porta seriale, è necessario chiamare qualcosa che causa il ridisegno del modulo in modo che venga richiamato il gestore di OnPaint. Ho provato questo.Refresh e questo.Invalidate, e ciò che accade è che perdo tutto ciò che è stato disegnato in precedenza sul modulo.

C'è un altro modo per raggiungere questo obiettivo senza perdere ciò che è stato disegnato sul modulo?

risposta

20

Il punto è che si dovrebbe pensare di memorizzare i dati del disegno da qualche parte. Come già detto, una bitmap del buffer è una soluzione. Tuttavia, se non si ha molto da disegnare, a volte è più facile e migliore memorizzare i dati del disegno in una variabile o in un array e ridisegnare tutto nell'evento OnPaint.

Supponiamo di ricevere alcuni dati punto che devono essere aggiunti al grafico. Firs di tutto si crea un elenco punto:

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

Poi ogni volta che si ottiene un nuovo punto si aggiunge alla lista e aggiornare la forma:

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

Nel caso in OnPaint inserire il seguente codice :

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

Questo funziona abbastanza velocemente fino a circa 100.000 punti e utilizza molto meno memoria rispetto alla soluzione bitmap del buffer. Ma dovresti decidere quale modo usare in base alla complessità del disegno.

+0

Grazie - funziona bene. Domanda veloce - Sto disegnando questo grafico a linee in tempo reale - alla fine ho intenzione di superare la larghezza massima disponibile sullo schermo, quindi voglio che le linee che ho disegnato sul modulo si spostino leggermente a sinistra, per fare spazio per il tracciamento delle nuove coordinate. Qualche suggerimento su come fare questo? Fondamentalmente sto sviluppando un'applicazione di tipo ECG semplice. – Chris

+2

Ci sono molti modi per farlo. Ad esempio, è possibile utilizzare e.Graphics.TranslateTransform (-x, 0); Ciò rende tutti i tuoi grafici da disegnare spostati a sinistra di x pixel. – Zenya

0

il modo predefinito per gestire questo è quello di creare una bitmap di memoria e disegnare su quella quindi impostare la proprietà dell'immagine della casella immagine sulla bitmap di memoria.

5

Come rerun ha detto, è necessario bufferizzare il modulo (poiché sembra che si sta scartando i dati dopo averlo disegnato).

Questo è fondamentalmente come lo farei:

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); 
    } 
} 

Detto questo, probabilmente desidera memorizzare nella cache i dati in modo è possibile modificare la dimensione del buffer in cui le modifiche di dimensione forma e quindi ridisegnare i vecchi dati su di essa.

0

È necessario memorizzare i dati storici da qualche parte e ridipingerli.

Questo sarà molto più facile che dire caching e bitmap di ritaglio.

1

La soluzione può essere this.Invalidate()

Problemi correlati