C# Chart zur Laufzeit "ohne DataBind()" verändern/ aktualisieren

FloDra

Newbie
Registriert
Apr. 2014
Beiträge
6
Hallo....

ich Programmiere gerade an ein Messprogramm und wollte mir ein "live" Diagramm anzeigen lassen.
Ich habe mir eine ArrayList (Collection) erzeugt in der ich die Messwerte die ich vom Messgerät bekomme als Frequenz(als xWert) und Pegel (als yWert) abspeichere.
Daraus möchte ich ein Diagramm erzeugen.

Da diese Messung recht Fix laufen muss, verwende ich keine Datenbank sondern nur die Collection und speichere da den MaxWert. Am Ende der Messung wird dann erst die Collection in die Datenbank geschrieben.

Wenn ich mir während der Laufzeit die Form anzeigen lasse mit dem Chart-Element erhalte ich den Hintergrund jedoch keine Datenreihe.
Erzeuge ich das Diagramm nach der Messung über einen Button wird es korrekt gezeichnet.

Meine Frage: Was benötige ich um es während der Laufzeit zu generieren? Bzw. was muss ich an meinen Code (siehe unten) ändern.

PS: Refresh() & Update() habe ich schon Probiert.

Code:
 public void ZeichneChart2()                         
        {
            chart1.Series.Clear();
            chart1.Series.Add("Series1");

            //Messpunkte messpunkte = new Messpunkte();

            //xWert
            double[] xval = new double[167];
            for (int index = 0; index != 167; index++)
            {
                xval[index]= messpunkte.GibFrequenz();
            }
            //yWert
            double[] yval = new double[167];
            for (int index = 0; index != 167; index++)
            {
                yval[index] = messpunkte.GibYWerte();
            }

            //Punkte hinzufügen
            for (int index = 0; index != 167; index++)
            {
                chart1.Series["Series1"].Points.AddXY(xval[index], yval[index]);
            }
            chart1.DataBind();
            chart1.Update();
            chart1.Refresh();  
        }
 
Hallo und herzlich willkommen bei ComputerBase

Zu deiner Frage.
1. Programmierst du mit WPF oder Windows Forms?

Bei WPF müsstest du mit Workern/Events arbeiten.

Grüße Matias
 
Hi,

die Form dürfte im gleichen Thread laufen, daher wirst du es erst sehen wenn es fertig gezeichnet ist.

Wenn du sowas machen willst solltest du dich in Richtung Hintergrundthread einarbeiten und den das bereitstellen der Werte machen lassen und nicht im gleichen Thread wie das GUI zeichnen.

Je nach .NET Version auch mit Async und Await oder eben (falls zu alt) mit einem Backgroundworker.

Ausser natürlich, ich verstehe jetzt dein Problem komplett falsch, ist nicht so ganz klar ersichtlich...

Wenn ich mir während der Laufzeit die Form anzeigen lasse mit dem Chart-Element erhalte ich den Hintergrund jedoch keine Datenreihe.
Erzeuge ich das Diagramm nach der Messung über einen Button wird es korrekt gezeichnet.

Meine Frage: Was benötige ich um es während der Laufzeit zu generieren? Bzw. was muss ich an meinen Code (siehe unten) ändern.

VG,
Mad
 
Ausser natürlich, ich verstehe jetzt dein Problem komplett falsch, ist nicht so ganz klar ersichtlich...

Mh vieleicht nochmal anders ausgedrückt. Ich bekomme von meinem Messgerät stendig neue Werte.
Diese Werte liegen in einem Frequenzbereich.
Die Werte sollen immer aktuell auf dem Bildschirm angezeigt werden (Realtime).
Das heist ich bekomme z.B. 160 Werte pro s im Bereich von 30-1000MHz
Diese sollen dann als Kurve oder Punkte auf dem Chart angezeigt werden und das jede Sekunde wieder.


sagt mir noch nix aber ich werd mich mal etwas einlesen...
 
Hi,

ok, dann solltest du mit den genannten Mitteln weiter kommen denke ich.

Das Problem ist im Grunde: alles passiert in einem Thread, und dieser eine Thread ist auch noch für die Darstellung zuständig. Solange was anderes gemacht wird wird die Oberfläche des Programms im Normalfall nicht aktualisiert, das kannst du nur über einen sogenannten Hintergrundthread (oder neuer eben mit Await und Async) lösen.

Wann genau rufst du denn deine Methode auf? Hast du schon mal durchdebuggt?

VG,
Mad
 
Danke schon mal...

Die Messung läuft in einer while-Schleife (Endloschleife) bis ich einen Button mit der Abbruch Bedingung betätige.
In der while-Schleife durchlaufe ich, mit einem Interface (Entwurfsmuster "Brücke"), dann die Methode wo das Diagramm gezeichnet werden soll.

Beim durchdebuggen ist soweit alles i.O.. Die Messwerte werden übergeben und auch die Series angelegt. Nur gezeichnet wird halt nicht. Weder Titel noch die Kurve.
Ich dachte ja dass mir ein Event fehlt um das Chart zu zeichnen, da es über den Button mit Button_click funktioniert. Aber dann bin ich auch nicht mehr in der Endlosschleife könnte auch damit zusammenhängen wie du ja meintest.
 
Hi,

vielleicht musst du noch ein wenig mehr Code posten, ich kann mir das gerade nicht vorstellen, wie es genau läuft bei dir. "Endlosschleife" klingt jedenfalls nie gut...

VG,
Mad
 
Ok das ist die Messchleife:
Code:
 //Endlos Messschleife
        public void MessSchleife()
        {

            //hier steht noch weiterer Code aber nur für das Messgerät bzw Datenbank unwichtig für mein Problem

            Messungläuft = true;
            while (Messungläuft)
            { 
                //Einstellung für das Messgerät
                nwa.Meas_S(21);
                nwa.MeasFormat(2);
                nwa.Scale_Auto();
                
                //Messwerte holen
                nwa.SendCommand("FORMAT ASC");                                       //Rückgabeformat
                nwa.SendCommand("FORMAT:DEXPORT:SOURCE DDATA");     //Was wird zurückgegeben (hier: Daten wie auf NWA Bildschirm)
                string nwa_rohdaten = nwa.SendCommand_In("TRAC? CH1DATA");  //von Port 1
                nwa_rohdaten = nwa_rohdaten.Trim();
                int wert = nwa_rohdaten.IndexOf("\n");
                if(wert > 0)
                    nwa_rohdaten = nwa_rohdaten.Substring(0, wert);
              
                string[] einzelwert = nwa_rohdaten.Split(',');      //Rohdaten split

                int i = 1;
                foreach (string item in einzelwert)                 //Schleife um Daten in Collection zu schreiben
                {
                    mp.Pegel = double.Parse(item.Replace('.',','));
                    frequenz = messpunkte.GibFrequenz();            //holt freq.
                    mp.Frequenz = frequenz;                         //Freq. Collection zuweisen
                    Console.WriteLine( i + ":  " + item + " aktuell Freq.: " + mp.Frequenz + " Pegel: " + mp.Pegel);
                    
                    messpunkte.SchreibenCollection(mp);             //in Collection schreiben
                    i++;            
                }
                this.aktualisieren(messpunkte);              //Diagramm aktualisieren
                Application.DoEvents();                         //reaktion auf Event bsp.: MessStop klick
            }
}

mit dem this.aktualisieren(messpunkte) rufe ich das Interface auf
(selbe Class wie Messprogramm)

Code:
 public void aktualisieren(Messpunkte messpunkte)
        {
            foreach (IBeobachter hörer in this.m_liste)
                hörer.benachrichtigen(messpunkte);
        }

Das Interface:

Code:
 public interface IBeobachter
    {
        void benachrichtigen(Messpunkte m);
    }

das Interface dann die methode Zeichnen
Code:
 void IBeobachter.benachrichtigen(Messpunkte messwerte)
        {
            ZeichneChart2();
        }
Ergänzung ()

Solange was anderes gemacht wird wird die Oberfläche des Programms im Normalfall nicht aktualisiert, das kannst du nur über einen sogenannten Hintergrundthread (oder neuer eben mit Await und Async) lösen.

Also Await und Async ist leider nicht möglich, da ich mit VisualStudio 2010 und 4.0.NET arbeite.

Nur so ne Überlegung kann ich nicht auch einen Task benutzen um das Diagramm zeichnen zu lassen? Und dann meine Messchleife auf den Task warten lassen? Task waren doch auch neue Threads oder nicht
 
Generell sollte man immer mit DataBindings arbeiten. In deinem Fall müsste das ohne große Änderungen damit gehen:
Code:
chart1.Series["Series1"].Points.DataBindXY(xval, yval);

Ansonsten musst du mit der DataSource arbeiten.
 
Zuletzt bearbeitet:
Hatt sich jetzt erledigt... hab das Diagramm jetzt doch aus der Datenbank geholt und mit DataBindings
 
Zurück
Oben