So I have this awesome pictureBox1 in my C# program. Every 5 second I call an time method like this:
public Form1()
{
InitializeComponent();
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
}
I am trying to change a property of a pictureBox object I got. But I get this error when trying to do so:
Error 1 An object reference is required for the non-static field, method, or property 'Simma.Form1.pictureBox1' C:\Users\John\Desktop\Simma\Simma\Form1.cs 39 13 Simma
The pictureBox1 is set to Public though.
The problem must be in the code you haven't shown us... presumably in OnTimedEvent.
The simplest fix is to make OnTimedEvent an instance method instead. This isn't a matter of accessibility (and the field shouldn't be public - make it private!) it's a matter of trying to use an instance field from a static method.
Note, however, that you also shouldn't try to access a UI element from a non-UI thread. Currently your timer will fire its event in a different thread, causing cross-thread issues.
The simplest fix for this is to use a System.Windows.Forms.Timer instead of a System.Timers.Timer.
Related
I have timer that starts counting when a certain event (someEvent) occurs for one second, if the event is fired again within this second I want the first timer to stop and starts counting again from 0 I tried this :
void someEvent (object sender, TextChangedEventArgs e )
{
aTimer = new System.Timers.Timer();
aTimer.Change(5000, 0);
aTimer.Elapsed += OnTimedEvent;
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
timer definition in the MainWindow:
private System.Timers.Timer aTimer;
According to this C# Timer.Change Method
But I get an error over aTimer.Change saying: "timer doesn't contain a definition of 'Change'."
This was implemented using WPF.
Namespaces Matter
.NET has quite a few timers classes, each of which have their own specific functionality and exposed methods, so it can be easy to get confused between the namespaces (as most of the classes are just called Timer).
You are currently using the System.Timers.Timer class, which primarily consists of the Start() and Stop() methods. If you want the Change() method, you would need to instead use an instance of the System.Threading.Timer class :
// Declare the timer as the other type of timer
aTimer = new System.Threading.Timer();
Yours is a System.Timers.Timer. This timer does not have a Change Method
The Timer.Change() event is used in System.Threading.Timer Timer.Change
I'm trying to get more familiar with eventhanlders, but my current even only updates once, I want it to update until I close the application.
This is my code:
private static event EventHandler Updater;
Updater += Program_updater;
Updater.Invoke(null, EventArgs.Empty);
Application.Run();
private static void Program_updater(object sender, EventArgs e)
{
KeyUtils.Update();
Framework.Update();
}
But like I said, it will only update once, I want it to update until I close my application. I know I can just do a While(true) but I rather not.
I think you want a Timer here:
Timer aTimer = new System.Timers.Timer(2000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += Program_updater;
// Have the timer fire repeated events (true is the default)
aTimer.AutoReset = true;
// Start the timer
aTimer.Enabled = true;
Specify callback:
private void Program_updater(Object source, System.Timers.ElapsedEventArgs e)
{
KeyUtils.Update();
Framework.Update();
}
Now every 2 seconds (or specify any other interval) callback OnTimedEvent will be called.
It is absolutely normal that your event is fired only once because the application starts only once.
What you acctualy need is to set up a timer and do some work on its tick.
Please have a look on example in answer for that question Simple example of the use of System. Timers. Timer in C#
Well it only updates once since you only invoke it once (I don't really get the context where your code runs since you both declare a static variable and invokes it on the same scope which is impossible).
If you want something to occur periodically you should use Timer, or in some cases AutoResetEvent/ManualResetEvent.
EventHandlers should be used only when you work as event driven which mean you want your handler to invoke When something happens
Here an example for [System.Timers.Timer][2] with your handler:
//Invoke every 5 seconds.
Timer timer = new Timer(5000);
//Add your handler to the timer invocation list.
timer.Elapsed += Program_updater;
//Start the timer.
timer.Start();
Also you need Program_update's signature to look like that:
private void Program_updater(object source, ElapsedEventArgs e)
So i created UserControl with dataGridView, actually how I will this object is less important, but let's say i have alredy DataSource and I want to refresh dataGridView with these values.
on example i have function fillDataGridView() and I want it to call every 2 minutes
I think that I could do this with Thread class, but w/o any success yet
How do you deal with UI refresh?
I know that this looks like "yet another guy with UI update problem", but from what I saw I really can't the easiest way to do it
public partial class Alertbox : UserControl
{
private static System.Timers.Timer aTimer;
public Alertbox()
{
InitializeComponent();
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(Update);
aTimer.Interval = 2000;
aTimer.Enabled = true;
}
public void Update(object source, ElapsedEventArgs e)
{
BT_AddTrigger.Text += "test"; // append to button text
}
}
It shout's that
An exception of type 'System.InvalidOperationException' occurred in
System.Windows.Forms.dll but was not handled in user code Additional
information: Cross-thread operation not valid: Control 'BT_AddTrigger'
accessed from a thread other than the thread it was created on.
Use a System.Windows.Forms.Timer instead of System.Timer.Timer.
You're getting the Cross Thread Operation Not Valid error because System.Timer.Timer runs on a different thread, and you can't invoke an operation on a Winforms thread from another thread without calling Control.Invoke().
System.Windows.Forms.Timer will use the same thread as the UI, and you'll avoid these problems.
You can use one of the handy Timer classes in .Net to trigger every 2 min.
Here is an example
http://msdn.microsoft.com/en-us/library/system.windows.forms.timer(v=vs.110).aspx
You can use System.Windows.Forms:
using System.Windows.Forms;
public Alertbox()
{
InitializeComponent();
var timer = new Timer {Interval = 2*60*1000};
timer.Tick += Timer_Tick;
timer.Start();
}
void Timer_Tick(object sender, EventArgs e)
{
BT_AddTrigger.Text += "test";
}
You should use timer class in this way
System.Timers.Timer testTimer = new System.Timers.Timer();
testTimer.Enabled = true;
//testTimer.Interval = 3600000; //1 hour timer
testTimer.Interval = 100000;// Execute timer every // five seconds
testTimer.Elapsed += new System.Timers.ElapsedEventHandler(FillGrid);
I am very new to all this so please bear with me! I am writing a small app to control my telescope, at the moment I can connect to it and tell it where to point. I want to have a couple of text boxes, or labels that constantly update with the telescopes position - T is the telescope object and I am calling T.Altitude, T.Azimuth, T.RightAscention and T.Declination and I want these values to update the four labels every half second or so. I assume I need to use a background worker but am I correct? Will I be able to access the Telescope object since it was created on the main thread? And how exactly do I do it all! This is what I have so far (and it aint much!)...
private void bw_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
string Az = T.Azimuth.ToString();
string Alt = T.Altitude.ToString();
string Dec = T.Declination.ToString();
string Ra = T.RightAscension.ToString();
System.Threading.Thread.Sleep(500);
}
In your case you should consider using one of the Timer classes. Those classes call a given delegate in specified intervals.
The Timer class from Windows.Forms namespace calls a delegate in UI thread, so you will not have to bother with dispatching or anything, but it might make UI less responsive if you call it too often.
Other Timers use separate threads, so you will need to use either Dispatcher object or SynchronizationContext object to modify UI values. You can read more about those on msdn.
The easiest way is probably as suggested to use a Windows.Forms.Timer to periodically update the Gui with current values from your Telescope (object).
As a side note, the Background Worker is kind of obsolete in C# 5.0 since it is much easier to use async/await (see this thread about async/await vs BackgroundWorker).
Here is an example implementation in WinForms which refreshes a set of labels every 500 milliseconds.
public partial class MyForm : Form
{
private readonly Timer _timer = new Timer();
public MyForm()
{
InitializeComponent();
_timer.Interval = 500;
_timer.Tick += TimerTick;
_timer.Enabled = true;
}
void TimerTick(object sender, EventArgs e)
{
_labelAzimuth.Text = T.Azimuth.ToString();
_labelAltitude.Text = T.Altitude.ToString();
_labelDeclination.Text = T.Declination.ToString();
_labelRightAscension.Text = T.RightAscension.ToString();
}
}
The following code hides a form for 10 seconds. Nothing too crazy.
Each time the button is pressed, it creates a new timer object that doesn't stop and just keeps going. My intuition tells me that if you end up pressing this button many times, you'll have a bunch of timers that are running when only one is necessary (or is my assumption incorrect?). Also, if I do need to stop and dispose this timer, would I just send it as an argument in RevealForm or have the timer be a class level variable and just stop/reset it each time?
private void ButtonHide_Click(object sender, EventArgs e) {
this.Visible = false;
System.Timers.Timer t = new System.Timers.Timer();
t.Elapsed += new ElapsedEventHandler(RevealForm);
t.Interval = 10000;
t.AutoReset = false;
t.Start();
}
private void RevealForm(object source, ElapsedEventArgs e) {
InvokeReveal();
}
private void InvokeReveal() {
if (InvokeRequired) {
Invoke(new Action(InvokeReveal));
}
else {
this.Visible = true;
}
}
Thanks much!
Create the timer in the class then call t.start() on each click.
No need to destroy/cleanup/etc. Just recycle the one you have.
Your assumption is correct - testing would have asserted such for you.
You could either:
A) Disable the timer after each execution (per-interval) and enable on click, or,
B) Stop and destroy the timer and create a new one with each click.
Either option will require a little refactoring of your existing code.
As for the second part of the question - how you stop the timer is preferential. in such a small application (if this is its function in entirety) then simply stopping the timer within the event handler (or related method) would just do the trick, though in order to access the Timer instance you would declare it at a higher level in scope (i.e not bound within the scope of the click event handler).
Generally, the first thing you do is stop the timer in your event handler.
If you just want one timer then make it a form level variable, start it in your ButtonHide_Click, then at the top of your RevealForm method, stop the timer.