I am building a win8 app which has 3 buttons(Button1, Button2 and StartButton) and timer in it. Button1 and Button2 are disabled. If clicked on StartButton, Button1 is enabled and the number of clicks within 20 secs is counted and displayed in a textblock1. After the timer is over Button1 is disabled and Button2 is enabled and clicks are counted and displayed in textblock2. My problem is that the timer ticks properly for Button1 and not for Button2. Timer becomes faster when button2 is enabled. Can someone help me?
My code is below:
private int count1=0;
private int count2=0;
private int clickCounter = 0;
private int timeLeft;
private DispatcherTimer timer;
private void StartTimer()
{
if (this.timer != null)
{
this.StopTimer();
}
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0,0,0,1);
timer.Tick += timer_Tick;
timer.Start();
}
private void StopTimer()
{
if (this.timer != null)
{
this.timer.Stop();
this.timer = null;
}
}
public void timer_Tick(object sender, object args)
{
if (timeLeft > 0)
{
timeLeft = timeLeft - 1;
timerTextBlock.Text = Convert.ToString(timeLeft);
this.StartButton.IsEnabled = false;
}
else
{
StopTimer();
if (clickCounter==2)
{
ShowResult();
this.Button2.IsEnabled = false;
this.StartButton.IsEnabled = false;
}
else
{
myMsg.Text = "Time's up!";
this.Button1.IsEnabled = false;
this.StartButton.IsEnabled = true;
}
}
}
private void Button1_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
count1++;
this.textblock1.Text=count1.ToString();
}
private void Button2_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
count2++;
this.textblock2.Text=count2.ToString();
}
public void ResetTimer()
{
timeLeft = 20;
}
private void StartButton_Click(object sender, RoutedEventArgs e)
{
clickCounter++;
if (textblock1.Text == "0")
{
ResetTimer();
StartTimer();
this.Button1.IsEnabled = true;
}
else
{
ResetTimer();
StartTimer();
this.Button2.IsEnabled = true;
}
}
Every time you call the StartTimer Method timer.Tick += timer_Tick; is executed. This means if you call StartTimer the second time, every tick will invoke two events. Split your code like:
private void InitTimer()
{
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0,0,0,1);
timer.Tick += timer_Tick;
}
private void StartTimer()
{
timer.Start();
}
and call InitTimer only ones. Another Option is to unregister your event in if (this.timer != null) with the code timer.Tick -= timer_Tick;
A second point I see is a naming conflict: You've got a private global variable timer and one variable timer in your StartTimer Method.
// Edit: Full updated code:
private int count1=0;
private int count2=0;
private int clickCounter = 0;
private int timeLeft;
private DispatcherTimer timer;
private void StartTimer() {
if (timer == null) {
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0,0,0,1);
timer.Tick += timer_Tick;
}
timer.Stop();
timeLeft = 20;
timer.Start();
}
public void timer_Tick(object sender, object args) {
if (timeLeft > 0) {
timeLeft = timeLeft - 1;
timerTextBlock.Text = Convert.ToString(timeLeft);
} else {
timer.Stop();
if (clickCounter==2) {
ShowResult();
Button2.IsEnabled = false;
StartButton.IsEnabled = false;
} else {
myMsg.Text = "Time's up!";
Button1.IsEnabled = false;
StartButton.IsEnabled = true;
}
}
}
private void Button1_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) {
count1++;
textblock1.Text=count1.ToString();
}
private void Button2_Click(object sender, Windows.UI.Xaml.RoutedEventArgs e) {
count2++;
textblock2.Text=count2.ToString();
}
private void StartButton_Click(object sender, RoutedEventArgs e) {
clickCounter++;
StartButton.IsEnabled = false;
if (textblock1.Text == "0"){
Button1.IsEnabled = true;
StartTimer();
} else {
Button2.IsEnabled = true;
StartTimer();
}
}
Related
How do I make this dispatch timer 1 line of code instead of this
private DispatcherTimer timer1;
public void InitTimer()
{
timer1 = new System.Windows.Threading.DispatcherTimer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = TimeSpan.FromMilliseconds(2000);
timer1.Start();
}
the x problem? it gets a null error when I uncheck it to disable it
private DispatchTimer timer1; //<- Main part of the problem?
public void InitTimer()
{
timer1 = new System.Windows.Threading.DispatcherTimer();
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = TimeSpan.FromMilliseconds(2000);
timer1.IsEnabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
if (AS.Vis.Visibility != Visibility.Visible == false)
{
AS.Vis.Visibility = Visibility.Hidden;
timer1.IsEnabled = false;
}
else
{
AS.Vis.Visibility = Visibility.Visible;
Comp();
}
}
private void AKS_Checked(object sender, RoutedEventArgs e)
{
InitTimer();
AS.Vis.Visibility = Visibility.Visible;
timer1.IsEnabled = true;// <-Also part of the problem
}
private void AKS_Unchecked(object sender, RoutedEventArgs e)
{
AS.Vis.Visibility = Visibility.Hidden;
timer1.IsEnabled = false; //<-The problem
}
I have tried some "work arounds" that I thought would end up working but they didn't so I came to the conclusion that if the dispatchtimer was one line of code it wouldn't cause a null error since private DispatchTimer timer1; bit of code wouldn't exist but I have been told that isn't really the problem?
Creating a new DispatcherTimer instance without stopping the recent and without unsubscribing from the DispatcherTimer.Tick event, keeps all the timers running forever and executing callbacks forever. This is what you are currently doing. Every call to AKS_Checked creates a new DispatcherTimer without stopping the running one and without cleaning up event handlers.
The following example is a refactored version of your code and guarantees that there will be only one single timer instance.
It also fixes the null-reference issue by initializing the private timer property properly.
DispatcherTimer.Start resets the timer and starts it.
partial class MainWindow : Window
{
private DispatcherTimer Timer { get; set; }
public void MainWindow()
{
InitializeComponent();
InitTimer();
}
private void InitTimer()
{
this.Timer = new System.Windows.Threading.DispatcherTimer();
this.Timer.Tick += OnTick;
this.Timer.Interval = TimeSpan.FromMilliseconds(2000);
}
private void OnTick(object sender, EventArgs e)
{
if (AS.Vis.Visibility == Visibility.Visible)
{
AS.Vis.Visibility = Visibility.Hidden;
this.Timer.Stop();
}
else
{
AS.Vis.Visibility = Visibility.Visible;
Comp();
}
}
private void AKS_Checked(object sender, RoutedEventArgs e)
{
AS.Vis.Visibility = Visibility.Visible;
// Reset and start the timer
this.Timer.Start();
}
private void AKS_Unchecked(object sender, RoutedEventArgs e)
{
AS.Vis.Visibility = Visibility.Hidden;
this.Timer.Stop();
}
}
If this is the real problem:
I just get a null reference when I try to disable the timer
Then try this, so the timer variable is initialised earlier.
private DispatchTimer timer1 = new System.Windows.Threading.DispatcherTimer();
public void InitTimer()
{
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Interval = TimeSpan.FromMilliseconds(2000);
timer1.Start();
}
This will initialise the variable when the class is created, before InitTimer (or your disable function) can be called.
I'm trying to do a program that presses a button, like I would just press it on my own keyboard.
It works perfectly in txt files, or somewhere else, but in game it just doesn't. The game is metin2.
Thank you!
public partial class Form1 : Form
{
int spaceCount = 0;
bool startPressed = false;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (!startPressed)
{
startPressed = true;
Timer timer = new Timer();
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = 1000;
timer.Enabled = true;
timer.Start();
}
}
void timer_Tick(object sender, EventArgs e)
{
InputSimulator IS;
IS = new InputSimulator();
IS.Keyboard.KeyPress(VirtualKeyCode.SPACE);
Keyboard.KeyPress(Keys.Space);
spaceCount++;
label1.Text = spaceCount.ToString();
}
}
}
how i can make a loop timer that check if in main form topmost.enable is false until a label is visible and then set to true when the label deactive?
If tried this code but not work:
private void InitializeAlive()
{
alive = new System.Timers.Timer();
alive.Interval = 1000;
alive.AutoReset = true;
alive.Elapsed += Alive_Tick;
alive.Start();
}
private void Alive_Tick(object sender, EventArgs e)
{
if (lblPassword.Enabled)
{
this.TopMost = false;
}
else
{
this.TopMost = true;
alive.Dispose();
}
}
private void btnPrint_Click(object sender, EventArgs e)
{
if (txtPassword.Text == pswd)
{
TopMost = false;
webPrintSetting.ShowPageSetupDialog();
InitializeAlive();
}
else
{
btnPrint.Enabled = false;
btnPrint.Visible = false;
lblPassword.Visible = false;
txtPassword.Enabled = false;
txtPassword.Visible = false;
txtPassword.Clear();
}
}
If you only need to do something when 'Enabled' property of the label changes, then you can simply add handler to the 'EnabledChanged' property, like this:
public Form1()
{
InitializeComponent();
lblPassword.EnabledChanged += new System.EventHandler(this.LblPassword_EnabledChanged);
}
And implement the handler like this:
private void LblPassword_EnabledChanged(object sender, EventArgs e)
{
TopMost = !lblPassword.Enabled;
}
I find a solution to toggle on/off topmost (off until a target process is running).
private Timer check;
public MyForm()
{
InitializeCheck();
}
private void InitializeCheck()
{
check = new Timer();
check.Interval = 5000;
check.Tick += Check_Tick;
check.Enabled = false;
}
private void Check_Tick(object sender, EventArgs e)
{
CheckProgram();
}
private void CheckProgram()
{
Process[] program = rocess.GetProcessesByName("notepad");
if (program.Length == 0)
{
check.Enabled = false;
TopMost = true;
}
private void button1_Click(object sender, EventArgs e)
{
TopMost = false;
check.Enabled = true;
}
I am working on a project which requires to start a Timer on load of the Form1 that increments the TimerCount Property of Class TimeCounter in the tick event.
The Project has also Form2 which when open I want to read the increment updates from TimeCounter class which is being incremented by the Form1 because Form1 is parent and will not close I tried to read from TimeCounter but got default set value which is 0.
Here is code:
Timer Class
public class TimeCounter
{
public int timer=0;
public int TimerCount { get; set; }
public int GetTime()
{
return timer;
}
}
Form1 Increment TimerCount After 1 Second
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
timer.Start();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
sk++;
Timer t = new Timer();
t.TimerCount = sk;
}
Form2 Which Receive Counter Continuously(But Not Working)
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Start();
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Timer t1 = new Timer();
B01CountDown.Text = t1.GetTime().ToString();
}
You are not passing the Timer object correctly to Form2. You need to pass the instance of Timer being used by form 1 to form 2.
Timer:
public class Timer
{
public int timer = 0;
public int TimerCount { get; set; }
public int GetTime()
{
return timer;
}
}
Form1:
public partial class Form1 : Form
{
private Timer _timer;
public Form1()
{
InitializeComponent();
_timer = new Timer();
timer1.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
timer1.Tick += timer1_Tick;
}
void timer1_Tick(object sender, EventArgs e)
{
_timer.TimerCount++;
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2(_timer);
frm2.ShowDialog();
}
}
Form2:
public partial class Form2 : Form
{
public Timer _timer;
public Form2(Timer timer)
{
InitializeComponent();
_timer = timer;
timer1.Start();
}
private void Form2_Load(object sender, EventArgs e)
{
timer1.Tick += timer1_Tick;
}
void timer1_Tick(object sender, EventArgs e)
{
label1.Text = _timer.TimerCount.ToString();
}
}
Output:
I have modified the code you have posted as follows. If you do not understand, then you need to start learning C#.
TimeCounter:
public class TimeCounter
{
public static int timer = 0;
public static int TimerCount
{
get
{
return timer;
}
set
{
timer = value;
}
}
}
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
new Form2().Show();
}
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
timer.Start();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
TimeCounter.TimerCount++;
}
}
Form 2:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
timer.Enabled = true;
timer.Start();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (B01CountDown.InvokeRequired)
{
B01CountDown.Invoke((MethodInvoker)(() =>
{
B01CountDown.Text = TimeCounter.TimerCount.ToString();
}));
}
}
}
Actually you don't require TimeCounter Class and also Timer in Form2
see below code
Form1
public partial class Form1 : Form
{
int sk = 0;
Form2 form2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 1000;
timer.Elapsed += timer_Elapsed;
timer.Start();
}
private void button1_Click_1(object sender, EventArgs e)
{
form2.Show();
}
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
// Do your Stuff
sk++;
form2.UpdateLabel(sk.ToString());
}
}
Form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public void UpdateLabel(string Message)
{
if (B01CountDown.InvokeRequired)
{
B01CountDown.Invoke((MethodInvoker)(() =>
{
B01CountDown.Text = Message;
}));
}
}
}
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();
}
}