I have this code which is used for countdown in C#. I can't seem to find why my variable t is null. I tried this code on a separate project and it works well. I tried to incorporate it into another project and it says that variable t is null.
public partial class tracker : Form
{
System.Timers.Timer t;
int h1, m1, s1;
public tracker()
{
InitializeComponent();
}
private void tracker_Load(object sender, EventArgs e)
{
t = new System.Timers.Timer();
t.Interval = 1000; //1s
t.Elapsed += OnTimeEventWork;
}
private void btnLogin_Click(object sender, EventArgs e)
{
t.Start();
btnLogin.Enabled = false;
richTextBox1.SelectionLength = 0;
richTextBox1.SelectedText = DateTime.Now.ToString("MM/dd/yyyy\n");
richTextBox2.SelectedText = "Time In\n";
richTextBox3.SelectedText = DateTime.Now.ToString("HH:mm:ss\n");
richTextBox4.SelectedText = "\n";
richTextBox5.SelectedText = "\n";
}
}
You are getting error t as null, because t.Start() is calling before instantiation of Timer object t.
To solve this issue, either instantiate before t.start() or create an object inside the constructor.
Like
public tracker()
{
InitializeComponent();
//Here you can instantiate Timer class
t = new System.Timers.Timer();
t.Interval = 1000; //1s
t.Elapsed += OnTimeEventWork;
}
private void tracker_Load(object sender, EventArgs e)
{
//Do NOT create object of Timer class here
}
private void btnLogin_Click(object sender, EventArgs e)
{
t.Start();
...
}
Related
I have a label that I want to update every 5 seconds. It should change from 1921 to 1922 onward till 1992. I have tried using a timer but it gave me an error about being accessed on the wrong thread. The code I used was:
public partial class Form1 : Form
{
int x = 1921;
public Form1()
{
InitializeComponent();
}
System.Timers.Timer myTimer = new System.Timers.Timer(1000);
private void UpdateLabel(object sender, ElapsedEventArgs e)
{
label1.Text = x.ToString();
x += 1;
}
private void Form1_Load(object sender, EventArgs e)
{
myTimer.Elapsed += UpdateLabel;
myTimer.Start();
}
}
Try this:
private void UpdateLabel(object sender, ElapsedEventArgs e)
{
//Invoke makes the UI thread call the delegate.
Invoke((MethodInvoker)delegate {label1.Text = x.ToString(); });
x += 1;
}
try this
private readonly object y = new object();
int x = 1921;
public Form1()
{
InitializeComponent();
}
System.Timers.Timer myTimer = new System.Timers.Timer(1000);
private void UpdateLabel(object sender, ElapsedEventArgs e)
{
Invoke((MethodInvoker)(() => { lock (y) { label1.Text = x.ToString(); x++; } }));
}
private void Form1_Load(object sender, EventArgs e)
{
myTimer.Elapsed += UpdateLabel;
myTimer.Start();
}
How can I implement the following in my piece of code written in WPF C#?
I have a ElementFlow control in which I have implemented a SelectionChanged event which (by definition) fires up a specific event when the control's item selection has changed.
What I would like it to do is:
Start a timer
If the timer reaches 2 seconds then launch a MessageBox saying ("Hi there") for example
If the selection changes before the timer reaches 2 seconds then the timer should be reset and started over again.
This is to ensure that the lengthy action only launches if the selection has not changed within 2 seconds but I am not familiar with the DispatcherTimer feature of WPF as i am more in the know when it comes to the normal Timer of Windows Forms.
Thanks,
S.
Try this:
private int timerTickCount = 0;
private bool hasSelectionChanged = false;
private DispatcherTimer timer;
In your constructor or relevant method:
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 1); // will 'tick' once every second
timer.Tick += new EventHandler(Timer_Tick);
timer.Start();
And then an event handler:
private void Timer_Tick(object sender, EventArgs e)
{
DispatcherTimer timer = (DispatcherTimer)sender;
if (++timerTickCount == 2)
{
if (hasSelectionChanged) timer.Stop();
else MessageBox.Show("Hi there");
}
}
Finally, to make this work, you just need to set the hasSelectionChanged variable when the selection has changed according to your SelectionChanged event.
I've figured the complete code out as such:
DispatcherTimer _timer;
public MainWindow()
{
_myTimer = new DispatcherTimer();
_myTimer.Tick += MyTimerTick;
_myTimer.Interval = new TimeSpan(0,0,0,1);
}
private void ElementFlowSelectionChanged(object sender, SelectionChangedEventArgs e)
{
_counter = 0;
_myTimer.Stop();
_myTimer.Interval = new TimeSpan(0, 0, 0, 1);
_myTimer.Start();
}
private int _counter;
public int Counter
{
get { return _counter; }
set
{
_counter = value;
OnPropertyChanged("Counter");
}
}
private void MyTimerTick(object sender, EventArgs e)
{
Counter++;
if (Counter == 2)
{
_myTimer.Stop();
MessageBox.Show(“Reached the 2 second countdown”);
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler e = PropertyChanged;
if (e != null)
{
e(this, new PropertyChangedEventArgs(propertyName));
}
}
look here is the code of how to use DispatherTimer and you can add your own logic in it. that will depends on you..
private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(2000);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, object e)
{
// show your message here..
}
To use a DispatcherTimer:
private DispatcherTimer _timer;
public void StartTimer()
{
if (_timer == null)
{
_timer = new DispatcherTimer();
_timer.Tick += _timer_Tick;
}
_timer.Interval = TimeSpan.FromSeconds(2);
_timer.Start();
}
void _timer_Tick(object sender, EventArgs e)
{
MessageBox.Show("Hi there");
_timer.Stop();
}
void SelectionChangedEvent()
{
StartTimer();
}
How can I increment a value per second, when I passed it from another page?
Here is some code , where I get the value from the previous page + I added the Timer.
The Problem is that the EventHandler that has to been created for the Tick, can t be set to OnNavigatedTo.
public partial class Page1 : PhoneApplicationPage
{
DispatcherTimer timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(.1) };
public Page1()
{
InitializeComponent();
this.timer.Tick += new EventHandler(OnNavigatedTo);
this.Loaded += new RoutedEventHandler(OnNavigatedTo);
}
private void ButtonToPage1(object sender, RoutedEventArgs e)
{
App app = Application.Current as App;
MessageBox.Show(app.storeValue);
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string QueryStr = "";
NavigationContext.QueryString.TryGetValue("myNumber", out QueryStr);
int test = (int.Parse(QueryStr));
}
try this:
DispatcherTimer tmr;
int test;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string QueryStr = "";
NavigationContext.QueryString.TryGetValue("myNumber", out QueryStr);
test = (int.Parse(QueryStr));
LoadTimer();
}
public void LoadTimer()
{
tmr = new DispatcherTimer();
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
tmr.Interval = new TimeSpan(0, 0, 1);
tmr.Tick += tmr_Tick;
tmr.Start();
});
}
void tmr_Tick(object sender, EventArgs e)
{
test++;
TextBlock.Text = test.ToString();
}
It isn't clear why you can't just follow the tutorial linked in your comment. I guess you misunderstand it and tried to handle Tick event using OnNavigatedTo() method. Yes, that won't work and you aren't supposed to do so.
You're supposed to simply attach event handler method in OnNavigatedTo :
private int myNumber;
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
string QueryStr = "";
NavigationContext.QueryString.TryGetValue("myNumber", out QueryStr);
myNumber = (int.Parse(QueryStr));
DispatcherTimer newTimer = new DispatcherTimer();
newTimer.Interval = TimeSpan.FromSeconds(1);
//attach event handler method for Tick event
newTimer.Tick += OnTimerTick;
//or attach anonymous method so you don't need OnTimerTick() method :
//newTimer.Tick += (o, e) => { myNumber++; };
newTimer.Start();
}
void OnTimerTick(Object sender, EventArgs args)
{
myNumber++;
}
I am in the process of creating my first c# project, a personal time tracking application. Pretty basic so far however before I get any further I would like to have the timer working properly.
So far the timer will start / stop and reset. However a curious thing that I wanted to be able to do was for the user to set a time and have the counter start from there.
So if they wanted to start at 20 minutes and have it count up, then it would
example: 00:20:00 would count from 20 and add to it.
However so far I have not figured it out.
Here is the code:
namespace TimeTracker
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
TimerBox.Text = string.Format("00:00:00");
}
int ss = 0;
public void StartButton_click(object sender, EventArgs e)
{
timer1.Start();
timer1.Enabled = true;
timer1.Interval = 1000;
}
public void StopButton_click(object sender, EventArgs e)
{
timer1.Stop();
TimerBox.Text = TimeSpan.FromSeconds(ss).ToString();
}
public void ResetButton_click(object sender, EventArgs e)
{
ss = 0;
TimerBox.Text = TimeSpan.FromSeconds(ss).ToString();
}
private void timer1_Tick(object sender, EventArgs e)
{
ss++;
TimerBox.Text = TimeSpan.FromSeconds(ss).ToString();
}
}
}
Here is the application:
http://imgur.com/VNXVrtp
Any help would be appreciated, I can provide more details if you would like!
EDIT: Since it was unclear, my question is:
What process would be better for coding this, adding to the integer or if there is a better way of implementing this?
You can set the initial value of that ss variable to any predefined integer entered by user, e.g.
DateTime _dt = DateTime.Parse(TimertBox.Text);
int ss = _dt.Second + _dt.Minute * 60 + _dt.Hour * 3600;
Try something like...
public partial class Form1 : Form
{
private TimeSpan Offset = new TimeSpan();
private System.Diagnostics.Stopwatch SW = new System.Diagnostics.Stopwatch();
public Form1()
{
InitializeComponent();
timer1.Interval = 1000;
UpdateTime();
}
public void StartButton_click(object sender, EventArgs e)
{
TimeSpan TS;
if (TimeSpan.TryParse(TimerBox.Text, out TS))
{
Offset = TS;
}
else
{
MessageBox.Show("Invalid Starting Time. Resetting to Zero");
Offset = new TimeSpan();
}
SW.Restart();
UpdateTime();
timer1.Start();
}
public void StopButton_click(object sender, EventArgs e)
{
SW.Stop();
timer1.Stop();
}
public void ResetButton_click(object sender, EventArgs e)
{
Offset = new TimeSpan();
if (SW.IsRunning)
{
SW.Restart();
}
else
{
SW.Reset();
}
UpdateTime();
}
private void timer1_Tick(object sender, EventArgs e)
{
UpdateTime();
}
private void UpdateTime()
{
TimerBox.Text = Offset.Add(SW.Elapsed).ToString(#"hh\:mm\:ss");
}
}
Try using the timer normally (from 00:00:00.00), and when updating your output label / textbox / etc. just add the time the user has written.
How do you pass the sender parameter to the system.timers.timer in .NET?
timer1[timer] = new System.Timers.Timer(interval);
timer1[timer].AutoReset = true;
timer1[timer].Elapsed += new ElapsedEventHandler(datatransferEvent);
timer1[timer].Start();
GC.KeepAlive(timer1[timer]);
private void timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
serverreconnected.Stop();
reconnect(_opcServer);
}
finally
{
serverreconnected.Start();
}
}
Example:
System.Threading.Timer timer1;
timer1= new System.Threading.Timer(databaseTrensfer, row, dueTime, interval);
public void databaseTrensfer(object row)
{
DataRow rowE = (DataRow)row;
}
Row pass to the parameter to the function databaseTrensfer()
I want to pass the the sender parameter to the event.
Thanks in advance.
I like zabulus's method, but there is an alternative. Create your own Timer class that inherits from System.Timers.Timer and it can hold anything you want. I chose to do the basic object Tag property so it can be reused in other projects.
public class MyTimer : System.Timers.Timer
{
public MyTimer(double interval)
: base(interval)
{
}
public object Tag { get; set; }
}
MyTimer timer;
void test(object sender)
{
timer = new MyTimer(1);
timer.Tag = sender;
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MyTimer timer = (MyTimer)sender;
object tag = timer.Tag;
// do whatever you want with tag
}
Then call test(with whatever value you want to pass).
create aggregation class that holds your row.
class RowHolderEventArgs : EventArgs
{
public DataRow row;
public RowHolderEventArgs(DataRow row)
{
this.row = row;
}
};
public delegate void RowHolderEvent(object sender, RowHolderEventArgs e);
class RowHolder
{
public event RowHolderEvent Elapsed;
DataRow row;
public RowHolder(DataRow row, Timer timer)
{
this.row = row;
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (this.Elapsed != null)
{
Elapsed(sender, new RowHolderEventArgs(row));
}
}
}
using
timer1[timer] = new System.Timers.Timer(interval);
rowHolder[timer] = new RowHolder(timer1[timer],row[timer]);
rowHolder.Elapsed+=new RowHolderEvent(databaseTrensfer)
public void databaseTrensfer(object sender, HolderEventArgs e)
{
DataRow rowE = (DataRow)e.row;
}
What about something like:
static Timer timer;
static void Main(string[] args)
{
var row = default(DataRow); // Some row
timer = new Timer(30000);
timer.Elapsed += (_, __) => databaseTrensfer(row);
}
static void databaseTrensfer(DataRow row)
{
// Do something with 'row'
}