I am coding in C#, and I have 3 variables that are being updated via my timer every 1000ms.
I want to use this timer to have a FastLine chart that plots the new points every 1000ms obviously.
I have got this working to a certain extent.
It is plotting each tick the timer does, but it just keeps adding to it i only want it to show the previous 20 plots, not the past 2000 if the program has been running that long.
My code below for the chart within my timer1_Tick method:
try
{
chart1.Series[0].Points.AddXY(xaxis++, CPUTemperatureSensor.Value);
chart1.Series[1].Points.AddXY(xaxis, NvdGPUTemperatureSensor.Value);
chart1.Series[2].Points.AddXY(xaxis, ramusedpt);
}
catch
{
}
xaxis is declared previously as an int, no need to show all code as rest is irrelevant
Below code is what was used to solve the problem, posted by the user jstreet
Link to the hread and his comment:
How to move x-axis grids on chart whenever a data is added on the chart
public partial class Form1 : Form
{
Timer timer;
Random random;
int xaxis;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
random = new Random();
timer = new Timer();
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
chart1.Series[0].Points.AddXY(xaxis++, random.Next(1, 7));
if (chart1.Series[0].Points.Count > 10)
{
chart1.Series[0].Points.Remove(chart1.Series[0].Points[0]);
chart1.ChartAreas[0].AxisX.Minimum = chart1.Series[0].Points[0].XValue;
chart1.ChartAreas[0].AxisX.Maximum = xaxis;
}
}
Related
I am trying to demonstrate file transfer in WPF so that it refreshes the screen in real time and shows the current data. My requirement is it should show the current file which is being transferred. This is my code I have written.
public MainWindow()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += tick_event;
timer.Start();
}
private void tick_event(object sender, EventArgs e)
{
for (int i = 0; i < 60; i++)
{
txtName.Text = "Transfering file no. "+i.ToString();
}
}
what I have tried is for instance there are 60 files and the screen show me which file is being transferred. But, when I run this code it shows me only the last file which is 59th file.
What changes I can make here to make this work? Thanks in advance.
When you say
it shows me only the last file which is 59th file
It is because when the event triggers it counts from 0 to 59 and it writes those numbers with no delay into txtName. The consecuence is that you only see the latest written number.
You should set a counter and in the timer event only write the counter variable.
DispatcherTimer timer = new DispatcherTimer();
private int filesCopied = 0;
public MainWindow()
{
InitializeComponent();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += tick_event;
timer.Start();
}
private void tick_event(object sender, EventArgs e)
{
filesCopied++;
txtName.Text = "Transfering file no. " + filesCopied.ToString();
if (filesCopied >= 60) timer.Stop();
}
I am writing a code in WPF & C# to display next sampling time in Date and time format.
For example, if sampling time is one minute and current time is 08:00 - the next sampling time should show 08:01, Next sampling time is displayed once 08:01 has passed.
I have tried using dispatcherTimer and sleep thread.
But when I use the whole WPF form freezes until next update.
Could you please help me?
code ->
public float samplingTime = 1;
public MainWindow()
{
InitializeComponent();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
tboxSampling.Text = DateTime.Now.AddSeconds(samplingTime).ToString();
void timer_Tick(object sender, EventArgs e)
{
System.Threading.Thread.Sleep((int)samplingTime*1000);
tboxSampling.Text = DateTime.Now.AddSeconds(samplingTime).ToString();
}
}
I'd use the DispatcherTimer for such a problem:
public float samplingTime = 1;
public MainWindow()
{
dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
tboxSampling.Text = DateTime.Now.AddSeconds(samplingTime).ToString();
}
Timers are not guaranteed to execute exactly when the time interval occurs, but they are guaranteed to not execute before the time interval occurs.
Before all. I'm not so good at this and hopefully you will understand it anyway.
Im making a function in my program where it checks to see if a row in a rtb is highlighted. If not, it highlights it.
For this to work I had to use different threads to be able to access the rtb from different places. My problem is that it creates a new "delegate"/instance/thread every time the timer refreshes. I would like to remove the old thread/delegate or replace it with the new.
Because now the program crashes after a while. It's a very small program but after 40 sec i reach over 3gb ram usage.
Thanks in advance!
Haris.
Code:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
What is happening if i am not mistaken is that you are creating and starting new timers exponentially. So your forms loads, Form1_Load method is called. Form1_Load creates a new timer that when elapsed, will call Form1_Load again. As the old timer not being disposed 2 timers are running now that will both create 2 new timers. 4 timers create 4 new so there are 8, 16, 32 and so on...
Basically what you have to do is call other method on timer elapsed:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += ATimer_Elapsed;//new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
RefreshColor();
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
Timer(); is only called ones thus creating only one timer.
Ok so please keep answers very direct and i must say i am very new to C#, i don't know a lot of stuff. Without further adieu my problem.
I am trying to move a picture box horizontally across the screen on a timer.The timer must go infinitely. I have tried all i currently know in C# and searched around quite a lot but nothing answered my exact question which is what i need because of my lesser knowledge of C#. For the last two weeks i worked on graphics mostly and the rest of that was trying to get this to work, So i have no code in my game. This is because for anything to work i need this part to be working. My game is 2D topdown. Any and all help is appreciated.
Thank you for taking the time to read.
Edit
No more answers needed, Thank you Odrai for the answer, it helped me a lot.
Use pictureBox.Location = new Point(x, y) or set pictureBox.Left/Top/Right. You can define x and y as variabels and initialize them with a default value. Increment x on timer tick.
Sample 1:
public partial class Form1 : Form
{
private Random _random
public Form1()
{
InitializeComponent();
_random = new Random();
}
private void timer1_Tick(object sender, EventArgs e)
{
int x = _random.Next(0, 500);
int y = _random.Next(0, 500);
pictureBox1.Top += y;
pictureBox1.Left += x;
}
}
Sample 2:
private void timer1_Tick(object sender, EventArgs e)
{
this.SuspendLayout();
pictureBox.Location = new Point(picust.Location.X + 10, picust.Location.Y);
this.ResumeLayout();
}
Add two buttons with title LEFT and RIGHT to a form and write the following code.
It might give you an idea, how to do simple moving animations.
public partial class Form1 : Form
{
int difference = 0;
Timer timer = new Timer();
public Form1()
{
InitializeComponent();
timer.Interval = 15;
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e)
{
pictureBox1.Left += difference;
}
private void btnLeft_Click(object sender, EventArgs e)
{
difference = -2;
}
private void btnRight_Click(object sender, EventArgs e)
{
difference = 2;
}
}
Try This Code it will work :
private void timer1_Tick(object sender, EventArgs e)
{
int width = this.Width; // get the width of Form.
if(pictureBox1.Location.X > width - pictureBox1.Width) //to check condition if pic box is touch the boundroy of form width
{
pictureBox1.Location = new Point(1, pictureBox1.Location.Y); // pic box is set to the new point. here 1 is indicate of X coordinate.
}
else
{
pictureBox1.Location = new Point(pictureBox1.Location.X + 100, pictureBox1.Location.Y); // to move picture box from x coordinate by 100 Point.
}
}
//Try This //
picturebox1.Location = 0,0;
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);
}
}