Start timer from different class - c#

In my form I have one button and one label, and in my class I have one timer and it should start with timer.Start();
I need help because I need to start the timer in my form with one button1_Click but I canĀ“t start the timer and where I should have the elapsed event in form or in class timer?
So when I click in the start button in my Form the timer should start, in my Timer.cs, and label in form should show timer time
Timer.CS
public class Timer
{
public string TimerType { get; set; }
public Timer PersonUnlimitedTimer { get; set; }
public enum TypeTimer { Unlimited, Countdown, Limited}
int timervalue;
int minute = 60;
int second = 0;
//Valor a ser alterado pelo user
int final = 1;
public Timer()
{
timervalue = final * minute;
PersonUnlimitedTimer = new Timer();
PersonUnlimitedTimer.Interval = 1000;
PersonUnlimitedTimer.Elapsed += _PersonUnlimitedTimer_Elapsed;
PersonUnlimitedTimer.Start();
}
public Timer(TypeTimer s1)
{
switch (s1)
{
case TypeTimer.Unlimited:
second++;
TimeSpan unlimited_timer = new TimeSpan(0, 0, second);
TimerTime = unlimited_timer.ToString();
break;
case TypeTimer.Countdown:
if (second != timervalue)
{
timervalue--;
TimeSpan countdown_timer = new TimeSpan(0, 0, timervalue);
TimerTime = countdown_timer.ToString();
}
else
{
PersonUnlimitedTimer.Stop();
}
break;
case TypeTimer.Limited:
if (second != timervalue)
{
second++;
TimeSpan limited_timer = new TimeSpan(0, 0, second);
TimerTime = limited_timer.ToString();
}
else
{
PersonUnlimitedTimer.Stop();
}
break;
default:
break;
}
}
public void _PersonUnlimitedTimer_Elapsed(object sender, ElapsedEventArgs e)
{
second++;
TimeSpan unlimited_timer = new TimeSpan(0, 0, second);
TimerTime = unlimited_timer.ToString();
}
}
and this is my form
namespace Time
{
public partial class Timers : Form
{
Timer timer;
public Timers()
{
InitializeComponent();
}
public Timers(Timertimer): this()
{
this.timer= timer;
timer.PersonUnlimitedTimer.Elapsed += PersonUnlimitedTimer_Elapsed;
}
void PersonUnlimitedTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lblTimerTime.Text = timer.TimerTime;
}
private void Timers_Load(object sender, EventArgs e)
{
}
private void btnStart_Click(object sender, EventArgs e)
{
timer.PersonUnlimitedTimer.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
timer.PersonUnlimitedTimer.Stop();
}
private void btnReset_Click(object sender, EventArgs e)
{
timer.PersonUnlimitedTimer.Stop();
lblTimerTime.Text = "00:00:00";
}
}
}

Related

Cant show result in array

I am new in the programming world and trying to do this little app for the first time working with WPF but I can't "print" my results from an array in the label.
public partial class MainWindow : Window
{
Stopwatch clock = new Stopwatch();
DispatcherTimer tick = new DispatcherTimer();
public int I = 0;
public string[] temporaryResult = new string[5];
public bool start = false;
public MainWindow()
{
InitializeComponent();
updates();
}
private void updates()
{
tick.Start();
tick.Tick += Tick;
}
private void Tick(object? sender, EventArgs e)
{
Display.Content = Math.Round(clock.Elapsed.TotalMilliseconds, 0);
test.Content = temporaryResult[I];
}
private void Start_Click(object sender, RoutedEventArgs e)
{
if (!start)
{
clock.Reset();
clock.Start();
start = true;
}
else
{
clock.Stop();
start = false;
temporaryResult[I] = clock.Elapsed.TotalMilliseconds.ToString();
I++;
Debug.Print(temporaryResult[1]);
}
}
}
In method tick, I try to show my result with
test.Content = temporaryResult[I];
It doesn't work. But when I use
test.Content = temporaryResult[0];
It works at least once.
Thanks for helping Xerillio!
You are incrementing I (I++) after you insert a value at temporaryResult[I] so I points to an empty index.

increment the textbox using multithreading

I want to create a C# form in which two text box show two different numbers.
After clicking on start button both numbers should start incrementing at same time should increment slowly so we can see them increment and clicking on stop button should stop increment.
Both text box are not related to each other any way.
public partial class Form1 : Form
{
Thread t1 = new Thread(new ThreadStart(increment1));
public static int fNumber = 0, sNumber = 0,flag = 0;
public Form1()
{
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
t1.Start();
}
private void button4_Click(object sender, EventArgs e)
{
}
private void number1_TextChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
public static void increment1()
{
Form1 frm = new Form1();
for (int i = fNumber;i<1000;i++)
{
frm.number1.Text = Convert.ToString(i);
}
}
}
public void Increment1()
{
for (int i = fNumber;i<1000;i++)
{
number1.Text = Convert.ToString(i);
number2.Text = Convert.ToString(i);
}
}
And just generally avoid static for threads. You can access your textboxes directly without the word this if you named your textboses number1 and number2. In a static method the variables need to be static aswell or you will get a compilation error.
For visibility, functions should have first letter in upper case. So you can distinguish them more easily from variables.
You are creating a new instance of Form1 which is wrong. Use the current Form1 that started the Thread.
Try
public partial class Form1 : Form
{
private Timer timer1;
public static int fNumber = 0, sNumber = 0,flag = 0;
public Form1()
{
timer1 = new Timer();
timer1.Interval = 1000;
timer1.Tick += timer1_Tick;
InitializeComponent();
}
private void Start_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void button4_Click(object sender, EventArgs e)
{
timer1.Stop();
}
private void number1_TextChanged(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void timer1_Tick(object sender, EventArgs e)
{
int i = 0;
int.TryParse(this.number1.Text, out i);
i++;
if(this.number1.InvokeRequired)
{
this.number1.BeginInvoke((MethodInvoker) delegate()
{
this.number1.Text = Convert.ToString(i);
});
}
else
{
this.number1.Text = Convert.ToString(i);
}
}
}
For safety measures, check if invoking is required.
Replace this.number1.Text = Convert.ToString(i); with this block of code.
if(this.number1.InvokeRequired)
{
this.number1.BeginInvoke((MethodInvoker) delegate()
{
this.number1.Text = Convert.ToString(i);
});
}
else
{
this.number1.Text = Convert.ToString(i);
}

C# - Progress bar wont display value

In my application I need a progress bar to display the progress of a plant growing. This would be the code:
private static Timer farmProgress;
internal void initFarmProgTimer( int step, int max = 100 )
{
farmProgress = new Timer();
farmProgress.Tick += new EventHandler(farmProgress_Tick);
farmProgress.Interval = step; // in miliseconds
farmProgress.Start();
}
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value = increment;
}
}
Here the call of the initFarmProgTimer function:
public static System.Threading.Timer growTimer;
public static void InitGrowTimer(int time, string name)
{
growTimer = new System.Threading.Timer(growTimer_Finished, null, time, Timeout.Infinite);
plantActive = true;
Menu menu = new Menu();
menu.initFarmProgTimer(time / 100);
}
Note that the class where this function is called from is NOT a form but the class where the function is defined IS a form.
Does anybody know what my error is?
edit
here is the call for the InitGrowTimer function
switch ( index )
{
case 0:
currentPlant = wheat.name;
plantQ = printPlantDatas("wheat");
if (plantQ == true)
{
InitGrowTimer(wheat.time, wheat.name);
wheat.planted++;
}
break;
}
You are setting the value to the progress bar which will only set the progress to the current value. You have to increment it rather. I have added the pluss (+) sign for you
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value += increment;
}
}
It is not clear to me what is on a Form and what isn't but assuming this is on the Form:
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
plantProgressBar.Value = increment;
}
}
Change it to this so that you update the control from the UI thread:
private void farmProgress_Tick(object sender, EventArgs e)
{
if (increment >= 100)
{
// wait till user get plant
}
else
{
increment++;
this.Invoke(new Action(() => {
plantProgressBar.Value = increment;
}));
}
}
Update
My answer is wrong, I didn't expect this, but I created a Forms application and this worked fine to increment the progressbar:
public partial class Form1 : Form
{
private Timer farmProgress;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
farmProgress = new Timer();
farmProgress.Tick += farmProgress_Tick;
farmProgress.Interval = 1000; // in miliseconds
farmProgress.Start();
}
void farmProgress_Tick(object sender, EventArgs e)
{
progressBar1.Value++;
}
}

Get value of TextBox if 1s elapsed after last change c#

how can I get the value of my textbox 1seconde after the last change .
I tried with Stopwatch and TimerStamp but I just get the time between two change I don't know how to get the value of textbox 1 seconde after.
Thanks for help!
Edit:
Stopwatch TimerBetweenWrite = new Stopwatch();
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
TimerBetweenWrite.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = TimerBetweenWrite.Elapsed;
if (Search.Text != null && ts.Seconds >= 1)
{
//doing my stuff
}
TimerBetweenWrite.Restart();
}
But this don't work like I want because we need to change the TextBox 1 seconde after last change. I want run a function 1 seconde after the last change of the TextBox but the user can continue to change the TextBox.
Final Edit:
That the code which work Thank's all for help!
public partial class ViewerPage : Page
{
System.Timers.Timer myTimer = new System.Timers.Timer(1000);
public ViewerPage()
{
InitializeComponent();
myTimer.Elapsed += new ElapsedEventHandler(myTimer_Elapsed);
}
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
myTimer.Stop(); //Reset timer
myTimer.Start(); //Restart it
}
private void myTimer_Elapsed(Object sender, ElapsedEventArgs e)
{
ThreadContext.InvokeOnUiThread(
delegate()
{
// Doing My Stuff
myTimer.Stop();
});
}
}
public static class ThreadContext
{
public static void InvokeOnUiThread(Action action)
{
if (Application.Current.Dispatcher.CheckAccess())
{
action();
}
else
{
Application.Current.Dispatcher.Invoke(action);
}
}
public static void BeginInvokeOnUiThread(Action action)
{
if (Application.Current.Dispatcher.CheckAccess())
{
action();
}
else
{
Application.Current.Dispatcher.BeginInvoke(action);
}
}
}
Timer myTimer = new Timer(1000);
myTimer.Elapsed += myTimer_Elapsed;
private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
myTimer.Stop(); //Reset timer
myTimer.Start(); //Restart it
}
private void myTimer_Elapsed(Object sender, ElapsedEventArgs e)
{
//Do your stuff
}
Explanation: Each time the text changes, the timer gets reset and started again. It will only tick if it's enabled (aka not stopped by the TextChanged event) for a second.
If you want it to tick only once and then stop, set the AutoReset property to true.
You could inherit from TextBox and raise your own StableTextChanged event. The new control will appear at the top of your ToolBox:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBoxEx1_StableTextChanged(object sender, EventArgs e)
{
label1.Text = ((TextBoxEx)sender).Text;
}
}
public class TextBoxEx : TextBox
{
public event dlgStableTextChanged StableTextChanged;
public delegate void dlgStableTextChanged(object sender, EventArgs e);
private System.Windows.Forms.Timer tmr;
public TextBoxEx()
{
tmr = new System.Windows.Forms.Timer();
tmr.Interval = 1000;
tmr.Tick += Tmr_Tick;
this.TextChanged += TextBoxEx_TextChanged;
}
private void Tmr_Tick(object sender, EventArgs e)
{
tmr.Stop();
if (this.StableTextChanged != null)
{
this.StableTextChanged(this, new EventArgs());
}
}
private void TextBoxEx_TextChanged(object sender, EventArgs e)
{
tmr.Stop();
tmr.Start();
}
}

Windows Store App Metronome

I am developing Windows Store Application. I need to implement a metronome. This metronome should have bpm settings. User should be able to increase/decrease it.
Here is my code so far:
namespace App1
{
public sealed partial class MainPage : Page
{
public class TickArgs : EventArgs
{
public DateTime Time { get; set; }
}
public class Metronome
{
public event TickHandler Tick = (m, e) => { };
public delegate void TickHandler(Metronome m, TickArgs e);
public void Start()
{
while (true)
{
System.Threading.Tasks.Task.Delay(3000);
Tick(this, new TickArgs { Time = DateTime.Now });
}
}
}
public class Listener
{
public void Subscribe(Metronome m, TextBlock tb, MediaElement mmx)
{
m.Tick += (mm, e) => mmx.Play();
}
}
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Metronome m = new Metronome();
Listener l = new Listener();
l.Subscribe(m, tbcheck, mediaElement1);
m.Start();
}
}
}
How can i modify this code to have BPM settings?
My regards
Instead of uisng Task.Delay it may be easier to just use a Timer
An you can just pass the BBM into the Start method and set the interval based on that
public class Metronome
{
private DispatcherTimer _timer;
public event TickHandler Tick;
public delegate void TickHandler(Metronome m, TickArgs e);
public Metronome()
{
_timer = new DispatcherTimer();
_timer.Tick += Timer_Tick;
}
private void Timer_Tick(object sender, EventArgs e)
{
if (Tick != null)
{
Tick(this, new TickArgs { Time = DateTime.Now });
}
}
public void Start(int bbm)
{
_timer.Stop();
_timer.Interval = TimeSpan.FromSeconds(60 / bbm);
_timer.Start();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Metronome m = new Metronome();
Listener l = new Listener();
l.Subscribe(m, tbcheck, mediaElement1);
m.Start(8); // 8bbm
}

Categories