How to run function, when the user finished typing? (C#) - c#

I have a text field in which the user inserts or typing text for further translation into another language. I need to run the function after the user finished typing - how to determine it?

!!! Note the order of settings for the timer
// Create a System.Timers.Timer
System.Timers.Timer aTimer = new System.Timers.Timer();
// On KeyUp, start the countdown
private void richTextBox1_KeyUp(object sender, KeyEventArgs e) {
aTimer.Interval = 1000; // time in ms (1 sec)
aTimer.AutoReset = false; // "false" - calls the event once, "true" - repeatedly
aTimer.Elapsed += OnTimeout; // event binding
aTimer.Enabled = true; // timer run
}
private void OnTimeout(object sender, ElapsedEventArgs e) {
if (InvokeRequired) Invoke(new Action(() => DoneTyping() ));
}
// User is "finished typing", do something
private void DoneTyping() {
// do something
}

Related

How to ignore first Interval on first run of System.Windows.Form.Timer?

I have a timer that repeats at 1 second intervals. Users can Start() or Stop() the timer.
System.Windows.Form.Timer timer = new();
timer.Interval = 1000;
timer.Tick += (sender, e) =>
{
// Perform the action...
}
The problem is that in case of timer.Stop() it reacts immediately after pressing, but in case of timer.Start() it works after 1 second. This may feel strange to users.
So I solved it like this:
System.Windows.Form.Timer timer = new();
timer.Interval = 1;
timer.Tick += (sender, e) =>
{
if (timer.Interval == 1)
{
timer.Interval = 1000;
}
// Perform the action...
}
private void StopButton_Click(object sender, EventArgs e)
{
timer.Stop();
timer.Interval = 1;
}
However, there is a problem that the timer's Interval must be continuously set to 1. One timer is fine, but having multiple complicates things.
Is there any other way?
Following comments from #jmcilhinney and #Zohar Peled, I solved it like this:
System.Windows.Form.Timer timer = new();
timer.Interval = 1000;
timer.Tick += (sender, e) =>
{
StartOnFirstTimer();
}
private void StartOnFirstTimer()
{
// Perform the action...
}
private void StartButton_Click(object sender, EventArgs e)
{
StartOnFirstTimer();
timer.Start();
}
It is extracted the part corresponding to the timer's Tick event into a method and call it before starting it.

Remove or Replace Invoke Delegate C#

Before all. I'm not so good at this and hopefully you will understand it anyway.
Im making a function in my program where it checks to see if a row in a rtb is highlighted. If not, it highlights it.
For this to work I had to use different threads to be able to access the rtb from different places. My problem is that it creates a new "delegate"/instance/thread every time the timer refreshes. I would like to remove the old thread/delegate or replace it with the new.
Because now the program crashes after a while. It's a very small program but after 40 sec i reach over 3gb ram usage.
Thanks in advance!
Haris.
Code:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
What is happening if i am not mistaken is that you are creating and starting new timers exponentially. So your forms loads, Form1_Load method is called. Form1_Load creates a new timer that when elapsed, will call Form1_Load again. As the old timer not being disposed 2 timers are running now that will both create 2 new timers. 4 timers create 4 new so there are 8, 16, 32 and so on...
Basically what you have to do is call other method on timer elapsed:
private void Timer()//Timer for color refresh
{
aTimer = new System.Timers.Timer(300);
aTimer.Elapsed += ATimer_Elapsed;//new ElapsedEventHandler(Form1_Load);
aTimer.AutoReset = true;
aTimer.Enabled = true;
}
private void ATimer_Elapsed(object sender, ElapsedEventArgs e)
{
RefreshColor();
}
private void RefreshColor()//Refreshing the color of selected row
{
this.Invoke((MethodInvoker)delegate
{
if (richTextBox1.SelectionBackColor != Color.PaleTurquoise)
{
HighlightCurrentLine();
}
});
}
private void Form1_Load(object sender, EventArgs e)
{
Timer();
RefreshColor();
Timer(); is only called ones thus creating only one timer.

changing text of button with timeout in c#

How can I change the text of button with timeout? I tried out with the following code but it is not working.
private void button1_Click(object sender, EventArgs e)
{
Stopwatch sw = new Stopwatch();
sw.Start();
if (button1.Text == "Start")
{
//do something
button1.Text = "stop"
if (sw.ElapsedMilliseconds > 5000)
{
button1.Text = "Start";
}
}
How can I correct my code?
You need to use Timer instead:
Timer t = new Timer(5000); // Set up the timer to trigger on 5 seconds
t.SynchronizingObject = this; // Set the timer event to run on the same thread as the current class, i.e. the UI
t.AutoReset = false; // Only execute the event once
t.Elapsed += new ElapsedEventHandler(t_Elapsed); // Add an event handler to the timer
t.Enabled = true; // Starts the timer
// Once 5 seconds has elapsed, your method will be called
void t_Elapsed(object sender, ElapsedEventArgs e)
{
// The Timer class automatically runs this on the UI thread
button1.Text = "Start";
}
Stopwatch is only for measuring how much time has passed since you called Start().
If you're using C# 5
private async void button1_Click(object sender, EventArgs e)
{
button1.Text = "Stop";
await Task.Delay(5000);
button1.Text = "Start";
}
You could use a timer. In this example the text of the button changes to "Stop" after 5 seconds.
private Timer timer = new Timer();
private void button1_Click(object sender, EventArgs e)
{
timer.Interval = 5000; // interval length
timer.Tick += TimerOnTick;
timer.Enabled = true; // activate timer
button1.Text = "Start";
}
private void TimerOnTick(object sender, EventArgs eventArgs)
{
timer.Enabled = false; // deactivate timer
button1.Text = "Stop";
}
I think you can reach your goal by using Timer
Example of using Timer
public partial class FormWithTimer : Form
{
Timer timer = new Timer();
public FormWithTimer()
{
InitializeComponent();
// Everytime timer ticks, timer_Tick will be called
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = (1000) * (1); // Timer will tick every second
timer.Enabled = true; // Enable the timer
}
// .......
showForm() // declaration
{
timer.start();
// .......
timer.stop();
}
void timer_Tick(object sender, EventArgs e)
{
//hide form...through visibility
}
}
Use this instead of Stopwatch:
private void button1_Click(object sender, EventArgs e)
{
button1.Text = "stop"
aTimer = new System.Timers.Timer(5000);
aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
aTimer.Enabled = true;
}
// Specify what you want to happen when the Elapsed event is raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
button1.Text = "Start";
var atim = source as Timer;
if (atim != null)
atim.Elapsed -= OnTimedEvent;
}

Timer continuously firing in C#, Not able to stop

Could any one help me to stop my timer in windows form C3 application? I added timer in form using designer and interval is set as 1000; I would like to do some actions after 5 seconds of waiting after button click. Please check the code and advise me. Problem now is I get MessageBox2 infinitely and never gets the timer stop.
static int count;
public Form1()
{
InitializeComponent();
timer1.Tick += timer1_Tick;
}
public void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = true;
while(count>5)
{
....dosome actions...
}
}
private void timer1_Tick(object sender, EventArgs e)
{
count1++;
MessageBox.Show("Messagebox2");
if (count1 == 5)
{
//timer1.Enabled = false; timer1.Stop();
((System.Timers.Timer)sender).Enabled = false;
MessageBox.Show("stopping timer");
}
}
I would render the count useless and just use the timer 1 interval property and put your actions in the timer1_Tick event.
public void button1_Click(object sender, EventArgs e)
{
timer1.Interval = 5000;
timer1.Enabled = true;
}
private void timer1_Tick(object sender, EventArgs e)
{
timer1.Enabled = false;
MessageBox.Show("stopping timer");
// Your other actions here
}
You are incrementing count1 and checking count.
while(count1 > 5)
{
...dosome actions...
}
Which Timer do you use? Because C# supports class Timer from two different namespaces. One is from Forms, the other is from System.Timers. I would suggest you to use the other one - System.Timers.Timer.
Timer t = new Timer(20000); // created with 20seconds
t.Enabled = true; // enables firing Elapsed event
t.Elapsed += (s, e) => {
\\do stuff
};
t.Start();
In this short code you can see how the timer is created and enabled. By registering to the Elapsed event you explicitly say what to do after the time elapses. and this is done just once. Of course, there are some changes needed in case user clicks button before your limit is reached. But this is highly dependent on behavior of the action you demand.

Changing label text property periodically

I have a label. I need to change the text property every 3 seconds. Please let me know how to do this. I tried using timer, but my application is going into infinite loop. I do not want this to happen/ Any help will be appreciated!
timer1.Interval = 5000;
timer1.Enabled = true;
timer1.Tick += new System.EventHandler (OnTimerEvent);
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
refreshStatusBar();
}
In your class constructor, you need to initialize the initial text for the Label and the .NET Framework's Timer component.
timer.Tick += new EventHandler(timer_Tick);
timer.Interval = (1000) * (3); // Timer will tick every 3 seconds
timer.Enabled = true;
timer.Start();
label.Text = DateTime.Now.ToString(); // initial label text.
Then in the timer's tick handler, update the Label's text property.
private void timer_Tick(object sender, ElapsedEventArgs e)
{
label.Text = DateTime.Now.ToString(); // update text ...
}
You should use thread, and when you want to stop call yourthread.Abort();
Update: SynchronizationContext method:
System.Threading.SynchronizationContext sync;
private void Form1_Load(object sender, System.EventArgs e)
{
sync = SynchronizationContext.Current;
System.Windows.Forms.Timer tm = new System.Windows.Forms.Timer { Interval = 1000 };
tm.Tick += tm_Tick;
tm.Start();
}
//Handles tm.Tick
private void tm_Tick(object sender, System.EventArgs e)
{
sync.Post(dopost, DateAndTime.Now.ToString());
}
public void dopost(string txt)
{
Label1.Text = txt;
}

Categories