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();
}
}
Related
I have a pair of com ports.one of them sends data and the other one reads data. I want it to send a command (p) automatically every five seconds and wait to get the answer and read it and the sends the command again. Now it just sends the command automatically every 5 seconds. I don't know what to add to wait for the answer...
private Timer _timer;
public Form1()
{
InitializeComponent();
_timer = new Timer();
_timer.Interval = 5000;
_timer.Tick += _timer_Tick;
}
private void _timer_Tick(object sender , EventArgs e)
{
SendData();
}
private void Form1_Load(object sender, EventArgs e)
{
btnSendData.PerformClick();
}
private void btnSendData_Click(object sender, EventArgs e)
{
if (!_timer.Enabled)
{
SendData();
_timer.Enabled = true;
}
else
{
_timer.Enabled = false;
}
}
private void SendData()
{
if (serialPort1.IsOpen)
{
dataOut = "P<CR>";
serialPort1.Write(dataOut);
}
}
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
dataIn = serialPort1.ReadExisting();
this.Invoke(new EventHandler(ShowData));
}
private void ShowData(object sender, EventArgs e)
{
tBoxDataIn.Text += dataIn;
}
I think this will be helpful:
async
await
Using async to create a task and then awaiting it is the way to go i think.
I am trying to increment an value in Arduino and send it on port and after that to display it in a label in real-time.
even that I put and delay(200) and Thread.sleep(200);
namespace Receiver
{
public partial class Form1 : Form
{
SerialPort port;
public Form1()
{
InitializeComponent();
this.FormClosed += new FormClosedEventHandler(Form1_FormClosed);
if (port == null)
{
port = new SerialPort("COM9", 9600);//Set your board COM
port.Open();
}
}
void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (port != null && port.IsOpen)
{
port.Close();
}
}
private void Afisare_Click(object sender, EventArgs e)
{
while (true)
{
string a = port.ReadExisting();
afisare.Text = a;
Thread.Sleep(200);
}
}
}
}
in change I got all the values, one by after one,down the screen some of them.
You are running an endless loop in your Afisare_Click handler that runs in the same thread as you UI. This means that the UI will not be able to render the control changes.
Thread.Sleep code switches the context to other threads, but not the UI thread.
Your approach should be using Timer.
public partial class Form1 : Form
{
private Timer _timer;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
_timer = new Timer();
_timer.Interval = 200;
_timer.Tick += _timer_Tick;
_timer.Enabled = true;
_timer.Start();
}
private void _timer_Tick(object sender, EventArgs e)
{
// This function will be called every 200 ms.
// Read the information from port, update the UI.
string a = port.ReadExisting();
afisare.Text = a;
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
_timer.Stop();
if (port != null && port.IsOpen)
{
port.Close();
}
}
}
private void timer3_Tick(object sender, EventArgs e)
{
}
Here is the full code to do that. Just add a Label named "label1" on your window.
public partial class Form1 : Form
{
private Timer timer3;
private int counter;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
counter = 0;
timer3 = new Timer();
timer3.Interval = 3000;
timer3.Tick += Timer3_Tick;
timer3.Start();
}
private void Timer3_Tick(object sender, EventArgs e)
{
counter++;
label1.Text = counter.ToString();
}
}
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;
}));
}
}
}
I have a function that displays numbers using a while loop but I want to stop execution of a while loop at random variable value using c# by clicking a button.
For Example:
private void FrqSent()
{
int i = 1;
while (i <= 5)
{
i = i + 1;
}
}
Here is a quick example on how you can use a Backgroundworker to accomplish your task:
public partial class Form1 : Form
{
private int i = 1;
public Form1()
{
InitializeComponent();
}
private void FrqSent()
{
while (i <= 500000000)
{
if (backgroundWorker1.CancellationPending)
{
break;
}
else
{
i = i + 1;
}
}
}
private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}
private void button2_Click(object sender, EventArgs e)
{
backgroundWorker1.CancelAsync();
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
FrqSent();
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show(i.ToString());
}
}
Just create a new Windows-Forms Project and add a backgroundworker object aswell as 2 buttons. You have to set the DoWork, RunWorkerCompleted and Click events manually.
Edit: Do not forget to set the BackgroundWorker`s WorkerSupportsCancellation property to true.
not very elegant but simple
public partial class Form1 : Form
{
private bool _stop;
public Form1()
{
InitializeComponent();
}
private void buttonStart_Click(object sender, EventArgs e)
{
_stop = false;
FrqSent();
}
private void buttonStop_Click(object sender, EventArgs e)
{
_stop = true;
}
private void FrqSent()
{
int i = 1;
while (i <= 5000000 && !_stop)
{
i = i + 1;
Application.DoEvents();
}
}
}