2016-06-29 12 views
0

Hier habe ich ein Diagramm (graph1), das normalerweise alle 1 Sekunde einen zufälligen Punkt hinzufügen sollte. aber es nicht ... Ich habe versucht, herauszufinden, was das Problem ist, aber hier habe ich keine Ideen mehr ... Der Timer ist gestartet, Label1 ändern sich jede Sekunde, aber das Diagramm ändert sich nicht ... mit Knopf eins, wenn ich darauf klicke, fügt einen neuen Punkt hinzu. Was habe ich vermisst? Bitte helfen Sie ... Vielen Dank.C# Echtzeitaktualisierung eines Diagramms

namespace Test_Chart1 
{ 
public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true; 
     graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true; 
     graph1.ChartAreas[0].AxisX.ScaleView.Size = 40; 
     System.Timers.Timer _Timer1s = new System.Timers.Timer(1000); //object 
     _Timer1s.Elapsed += _Timer1sElapsed;       //event in object 
     _Timer1s.Start();            //start counting    
    } 
    private void _Timer1sElapsed(object sender, EventArgs e)//Timer each 100ms 
    {   
     if (label1.BackColor == Color.Red) 
     { 
      label1.BackColor = Color.Blue; 
      PutValueInGraph1();    
     } 
     else label1.BackColor = Color.Red;    
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     PutValueInGraph1(); 
    } 
    private void PutValueInGraph1() 
    { 
     graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true; 
     graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true; 
     graph1.ChartAreas[0].AxisX.ScaleView.Size = 100; 
     Random Rand_Value = new Random(); 
     int ValueToAdd = Rand_Value.Next(1, 100); 
     listBox1.Items.Add(ValueToAdd.ToString()); 
     graph1.Series["Data1"].Points.AddY(ValueToAdd); 
     if (graph1.ChartAreas[0].AxisX.Maximum-10 > graph1.ChartAreas[0].AxisX.ScaleView.Size) 
     { 
       graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum); 
      graph1.Series["Data1"].Points.RemoveAt(0); 
     } 
    } 
} 
} 

ok hier ist die neue:

public partial class Form1 : Form 
{ 
static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer(); 

    public Form1() 
    { 
     InitializeComponent(); 
     myTimer.Tick += new EventHandler(TimerEventProcessor); 
     myTimer.Interval = 1;   
    } 

    private void TimerEventProcessor(Object myObject, EventArgs myEventArgs) 
    { 
     Random Rand_Value = new Random(); 
     int ValueToAdd = Rand_Value.Next(1, 100); 
     listBox1.Items.Add(ValueToAdd.ToString()); 
     graph1.Series["Data1"].Points.AddY(ValueToAdd); 
     if (graph1.ChartAreas[0].AxisX.Maximum - 10 > graph1.ChartAreas[0].AxisX.ScaleView.Size) 
     { 
      graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum); 
      graph1.Series["Data1"].Points.RemoveAt(0); 
     } 
    } 
    private void btn_Start_Click_1(object sender, EventArgs e) 
    { 
     graph1.ChartAreas[0].AxisX.ScrollBar.Enabled = true; 
     graph1.ChartAreas[0].AxisX.IsLabelAutoFit = true; 
     graph1.ChartAreas[0].AxisX.ScaleView.Size = 100; 
     myTimer.Start(); 
     BlinkLed.BackColor = Color.YellowGreen; 
    } 
    private void btn_Stop_Click(object sender, EventArgs e) 
    { 
     myTimer.Stop(); 
     BlinkLed.BackColor = Color.AliceBlue; 
    } 
} 

Glauben Sie, es ist besser? Was ist mit dem wechselnden Gewinde?

Wenn ich einen Knopf hatte:

private void PutValueInGraph1() 
    { 
     Random Rand_Value = new Random(); 
     int ValueToAdd = Rand_Value.Next(1, 100); 
     listBox1.Items.Add(ValueToAdd.ToString()); 
     graph1.Series["Data1"].Points.AddY(ValueToAdd); 
     if (graph1.ChartAreas[0].AxisX.Maximum-10 > graph1.ChartAreas[0].AxisX.ScaleView.Size) 
     { 
      graph1.ChartAreas[0].AxisX.ScaleView.Scroll(graph1.ChartAreas[0].AxisX.Maximum); 
      graph1.Series["Data1"].Points.RemoveAt(0); 
     } 
    } 

    private void button1_Click(object sender, EventArgs e) 
    {//try to raise exception 
     PutValueInGraph1(); 
    } 

und ich ändern, um die Veranstaltung wie folgt aus:

private void TimerEventProcessor(Object myObject, EventArgs myEventArgs) 
    {//try to raise exception 
     PutValueInGraph1(); 
    } 

Die Eingangsdaten beschleunigen, wenn ich den Timer und ich auf die ganze Zeit auf mich gestartet der Knopf1.

Warum gibt es keine Ausnahme, wie tom_imk sagte ?? weil wir auf die gleiche Funktion gleichzeitig zugreifen können ....?

Vielen Dank für Ihre Antworten.

+0

Start Timer von Taste –

+0

In der ersten Version klicken Sie System.Timers.Timer verwendet, jetzt verwenden Sie einen System.Windows.Forms.Timer, das ist der entscheidende Unterschied. –

Antwort

0

Ich bin überrascht, dass Sie nicht eine Ausnahme bekommen haben. Sie bearbeiten UI-Elemente außerhalb des UI-Threads, was Sie nie tun sollten.

Siehe die Antwort auf diese Frage: How to update the GUI from another thread in C#?

EDIT: Um deutlich zu machen, warum die timerelapsed Methode auf dem UI-Thread nicht ausgeführt wird: Es ist einfach die falsche Klasse, die hier verwendet wird. Die einfache Lösung wäre also, keinen System.Timers.Timer im Form-Konstruktor zu erstellen, sondern einen Timer auf das Formular im Formular-Designer zu setzen und stattdessen zu verwenden. Die Lösung von sowjanya attaluri sollte als die richtige Antwort markiert werden.

+0

Ich sehe den Punkt nicht. Sprechen Sie über Label1? Wenn ja, wird Label1 nur im Falle eines Ereignisses geändert ... welcher andere Thread greift darauf zu? – Jablonovo

+0

Die erste Version des OP-Codes verwendet einen System.Timers.Timer, während er einen System.Windows.Forms.Timer verwenden sollte, der in den Formular-Designer integriert ist. Das heißt, der Temerelapsed wird außerhalb des UI-Threads ausgeführt. Ich habe den genauen Code (erste veröffentlichte Version) erstellt und konsistente Ausnahmen erhalten. Ich werde meine Antwort so bearbeiten, dass sie genau auf die Zeit verweist. –

+0

Ok danke für die Erklärung !! – Jablonovo

0

Ich habe versucht, unter Codebeispiel und es funktioniert gut für mich.

public Form7() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     chart1.ChartAreas[0].AxisX.Maximum = 100; 
     chart1.ChartAreas[0].AxisX.Minimum = 0; 
     chart1.ChartAreas[0].AxisX.Interval = 1; 

     timer1.Start();   
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     Random Rand_Value = new Random(); 
     int ValueToAdd = Rand_Value.Next(1, 100); 
     chart1.Series[0].Points.AddY(ValueToAdd); 
    } 
+0

danke! aber ich weiß nicht warum es vorher nicht geklappt hätte .... – Jablonovo

+0

Ich denke du musst den Timer per Knopfklick starten. Wenn es gut funktioniert, markieren Sie es als eine Antwort –

Verwandte Themen