简体   繁体   中英

C# refreshing a chart every few seconds

I have a Windows Forms App written in C#. The idea is, that it draws a chart for 10 numbers after clicking a button. This works fine. I click the button, and I get a nice chart. However I also want to include a sort of "auto refresh" mode, where the chart is refreshed every few seconds. This would be enabled via Checkbox . Here's my code:

private void chartButton_Click(object sender, EventArgs e) //draw a chart after the button is clicked
{
   Random rdn1 = new Random();
   int value;

   foreach (var series in ekran.Series) //clear previous values
   {
      series.Points.Clear();
   }

   for (int i = 0; i < 10; i++) //draw a chart from ten new values
   {
      value = rdn1.Next(0, 10); //for testing purpouses the value will be a random number a random number
      ekran.Series["seria1"].Points.AddXY(i, value);
   }
}

private void checkBox1_CheckedChanged(object sender, EventArgs e) 
{
   while(checkBox1.Checked) //click the chartButton every one second, when the checkbox is checked
   {
      //rysuj.PerformClick(); 
      chartButton.PerformClick();
      Thread.Sleep(1000);
   }
}   

And now for my problem. When I check the Checkbox , I will not get a chart until it finishes every iteration of the while loop. Since it's an infinite loop, I will never get my chart. If I rewrite the code to make only five iterations when the Checkbox is checked, I only get the chart for the fifth one (and after five seconds, as to be expected).

So my question is: how can I force this to draw a chart every time the button is clicked via chartButton.PerformClick() ? When I click the button manually, everything works fine, it's just when I try to do it automatically, I get my problem.

EDIT First of all,thank you for the replies. However, I'm still experiencing the same problem when using a timer. This is how my code looks now:

namespace ChartTest
{
public partial class Form1 : Form
{

    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();


    public Form1()
    {
        InitializeComponent();
        timer.Tick += new EventHandler(timer_Tick);
        timer.Interval = 1000;
    }

    void timer_Tick(object sender, EventArgs e)
    {
        timer.Enabled = false;
        chartButton.PerformClick();

    }        

    private void checkBox1_CheckedChanged(object sender, EventArgs e)
    {

        while (checkBox1.Checked)            
        {
            timer.Enabled = true;                       // Enable the timer
            timer.Start();                              // Start the timer
        }

    }

    private void chartButton_Click(object sender, EventArgs e)      //draw a chart after the button is clicked
    {
        Random rdn1 = new Random();
        int value;

        ekran.Series.Clear();

        var series2 = new System.Windows.Forms.DataVisualization.Charting.Series
        {
            Name = "Series2",
            Color = System.Drawing.Color.Green,
            IsVisibleInLegend = false,
            IsXValueIndexed = true,
            ChartType = SeriesChartType.Line
        };
        this.ekran.Series.Add(series2);

        for (int i = 0; i < 100; i++)
        {
            value = rdn1.Next(0, 10);
            series2.Points.AddXY(i, value);
        }

    }

}
}

Sorry for being a total noob, but I have no idea, what am I doing wrong this time.

This is exactly what a Timer is for. Have the checkbox start/stop or enable/disable the timer, and handle the Timer.Tick event to redraw your chart. In your case, the event handler could simply call chartButton.PerformClick() , or insert whatever code the PerformClick() does.

ETA: If the chart refresh is not instant, you will probably want to push it off to a separate thread. If it's instant, there's not really any need to deal with the threading though.

I would go the route of using a thread with combination of checkbox's checkChange() event. Essentially this will allow your application to keep running while the update code will execute periodically. The refresh is determined by the sleep time, not your manual click or any other value.. Example below on how I to do this:

Thread refreshThread = null;

private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
   if (refreshThread == null) //No thread running, assume it starts this way
   {
      refreshThread = new Thread(chartRefresh);
      refreshThread.Start();
   }
   else //Thread is running, must terminate
   {
      refreshThread.Abort();
      refreshThread = null;
   }
}

private void chartRefresh()
{
   while (true)
   {
      //code to refresh chart
      Thread.Sleep(10000);
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM